From e2caf5365465254e8f5563f1dcbeeed9e32710af Mon Sep 17 00:00:00 2001 From: Mark Worrall Date: Wed, 8 Feb 2023 08:01:04 +0000 Subject: [PATCH 01/54] First version of single GPU sampling working --- .../supervised_finetuning/configs/config.yaml | 49 +++++++-------- model/supervised_finetuning/requirements.txt | 2 +- model/supervised_finetuning/trainer.py | 36 ++++++++--- model/supervised_finetuning/utils.py | 59 ++++++++++++++++++- 4 files changed, 112 insertions(+), 34 deletions(-) diff --git a/model/supervised_finetuning/configs/config.yaml b/model/supervised_finetuning/configs/config.yaml index 1d196fb2..925b6dda 100644 --- a/model/supervised_finetuning/configs/config.yaml +++ b/model/supervised_finetuning/configs/config.yaml @@ -16,29 +16,32 @@ defaults: eval_accumulation_steps: freeze_layer: datasets: - - webgpt - - prompt_dialogue - - squad_v2 - - adversarial_qa - - trivia_qa_nocontext - - xsum - - cnn_dailymail - - prompt_dialogue - - multi_news - - scitldr - - soda - - joke - - gsm8k - - dive_mt - - wmt2019_zh-en - - wmt2019_ru-en - - wmt2019_de-en - - ted_trans_nl-en - - ted_trans_de-ja - - instruct_tuning - - wmt2019_de-en - - samsum - - soda_dialogue + - webgpt: + fraction : 0.001 + - prompt_dialogue: + size : 10 + - squad_v2: + size : 10 + # - adversarial_qa + # - trivia_qa_nocontext + # - xsum + # - cnn_dailymail + # - prompt_dialogue + # - multi_news + # - scitldr + # - soda + # - joke + # - gsm8k + # - dive_mt + # - wmt2019_zh-en + # - wmt2019_ru-en + # - wmt2019_de-en + # - ted_trans_nl-en + # - ted_trans_de-ja + # - instruct_tuning + # - wmt2019_de-en + # - samsum + # - soda_dialogue cache_dir: .cache loss_fn: CrossEntropyLoss eval_size: diff --git a/model/supervised_finetuning/requirements.txt b/model/supervised_finetuning/requirements.txt index 8f8cc63c..efe6df89 100644 --- a/model/supervised_finetuning/requirements.txt +++ b/model/supervised_finetuning/requirements.txt @@ -4,7 +4,7 @@ datasets==2.8.0 deepspeed==0.7.7 evaluate==0.4.0 gdown -mpi4py==3.1.4 +# mpi4py==3.1.4 nltk==3.8.1 numpy>=1.22.4 py7zr diff --git a/model/supervised_finetuning/trainer.py b/model/supervised_finetuning/trainer.py index 0acb10dd..06ae39db 100644 --- a/model/supervised_finetuning/trainer.py +++ b/model/supervised_finetuning/trainer.py @@ -8,7 +8,8 @@ import torch from torch import nn from transformers import PreTrainedModel, Trainer, TrainingArguments from transformers.training_args import OptimizerNames -from utils import get_dataset, get_loss, get_metrics, get_model, get_tokenizer, read_yamls +from utils import (build_train_sampler, get_dataset, get_loss, get_metrics, + get_model, get_tokenizer, read_yamls) def compute_metrics(eval_pred, preprocess_fns, metrics): @@ -30,6 +31,7 @@ class SFTTrainer(Trainer): self, model: Union[PreTrainedModel, nn.Module] = None, args: TrainingArguments = None, + sampler: torch.utils.data.sampler.Sampler = None, loss_function: str = "CrossEntropyLoss", poly_eps: float = 1.0, **kwargs, @@ -38,6 +40,7 @@ class SFTTrainer(Trainer): # By default CrossEntropyLoss ignores padding_index -100, but just in case use our own loss_fct self.loss_fct = get_loss(loss_function, poly_eps) + self.sampler = sampler def compute_loss(self, model, inputs, return_outputs=False): labels_mask = inputs.pop("label_masks") @@ -88,6 +91,22 @@ class SFTTrainer(Trainer): return (loss, logits, labels) + def get_train_dataloader(self): + if self.sampler is None: + torch.utils.data.DataLoader( + self.train_dataset, + batch_size=self.args.per_device_train_batch_size, + shuffle=True, + collate_fn=self.data_collator + ) + else: + return torch.utils.data.DataLoader( + self.train_dataset, + batch_size=self.args.per_device_train_batch_size, + sampler=self.sampler, + collate_fn=self.data_collator + ) + def _strtobool(x): return bool(strtobool(x)) @@ -141,8 +160,8 @@ if __name__ == "__main__": model = get_model(training_conf, tokenizer) train, evals, collate_fn = get_dataset(training_conf, tokenizer) + sampler = build_train_sampler(training_conf, train.datasets) metrics, preprocess_fns = get_metrics(training_conf, tokenizer) - optimizer = OptimizerNames.ADAMW_BNB if training_conf.quantization else OptimizerNames.ADAMW_HF if training_conf.quantization: @@ -159,7 +178,7 @@ if __name__ == "__main__": learning_rate=float(training_conf.learning_rate), deepspeed="configs/zero_config.json" if training_conf.deepspeed else None, optim=optimizer, - fp16=True, + # fp16=True, local_rank=training_conf.local_rank, gradient_checkpointing=training_conf.gradient_checkpointing, gradient_accumulation_steps=training_conf.gradient_accumulation_steps, @@ -177,19 +196,20 @@ if __name__ == "__main__": ) assert len(evals) > 0 - if not training_conf.deepspeed or training_conf.local_rank == 0: import wandb wandb.init( project="supervised-finetuning", - entity=training_conf.wandb_entity, + # entity=training_conf.wandb_entity, + entity="maw501", name=f"{training_conf.model_name}-{training_conf.log_dir}-finetuned", ) - + trainer = SFTTrainer( - model, - args, + model=model, + args=args, + sampler=sampler, loss_function=training_conf.loss_fn, poly_eps=training_conf.poly_eps, train_dataset=train, diff --git a/model/supervised_finetuning/utils.py b/model/supervised_finetuning/utils.py index f7a0ab15..6d6b271a 100644 --- a/model/supervised_finetuning/utils.py +++ b/model/supervised_finetuning/utils.py @@ -2,9 +2,10 @@ from pathlib import Path import evaluate +import random # import nltk -# import numpy as np +import numpy as np import transformers import yaml from custom_datasets import get_one_dataset @@ -14,6 +15,35 @@ from losses import CrossEntropyLoss, PolyLoss from models import freeze_top_n_layers, get_specific_model from sklearn.model_selection import train_test_split from torch.utils.data import ConcatDataset, Subset +from torch.utils.data.sampler import Sampler + + +class ClassSampler(Sampler): + """Sampler which returns a fixed number of samples per class, per epoch""" + def __init__(self, class_labels, class_sizes): + self.class_labels = class_labels + self.class_sizes = class_sizes + + def __iter__(self): + out = [] + for i, _class in enumerate(np.unique(self.class_labels)): + class_idx = np.argwhere(self.class_labels == _class).flatten() + sampled_idx = random.sample(list(class_idx), int(self.class_sizes[i])) + out.extend(sampled_idx) + random.shuffle(out) + return iter(out) + + def __len__(self): + return int(sum(self.class_sizes)) + + +def build_train_sampler(training_conf, datasets): + train_sizes = [len(x) for x in datasets] + fractions = get_dataset_fractions(training_conf.datasets, train_sizes) + dataset_size_per_epoch = [int(size * frac) for size, frac in zip(train_sizes, fractions)] + dataset_labels = [[i] * d for i, d in zip(range(len(dataset_size_per_epoch)), dataset_size_per_epoch)] + dataset_labels = [i for s in dataset_labels for i in s] + return ClassSampler(dataset_labels, dataset_size_per_epoch) def get_tokenizer(conf): @@ -115,10 +145,35 @@ def get_model(conf, tokenizer): return model +def get_dataset_name_from_data_config(data_config): + if isinstance(data_config, dict): + return list(data_config.keys())[0] + return data_config + + +def get_dataset_fractions(conf, dataset_sizes): + fractions = [] + for i, data_config in enumerate(conf): + dataset_name = get_dataset_name_from_data_config(data_config) + if isinstance(data_config, dict): + if "fraction" in data_config[dataset_name]: + fractions.append(min(1, data_config[dataset_name]["fraction"])) + elif "size" in data_config[dataset_name]: + if data_config[dataset_name]["size"] > dataset_sizes[i]: + raise ValueError(f"Please specify a size smaller than number of examples ({dataset_sizes[i]})") + fractions.append(data_config[dataset_name]["size"] / dataset_sizes[i]) + else: + raise ValueError("Please specify either fraction or size in config.yaml") + else: + fractions.append(1) + return fractions + + def get_dataset(conf, tokenizer): train_datasets, evals = [], {} - for dataset_name in conf.datasets: + for data_config in conf.datasets: + dataset_name = get_dataset_name_from_data_config(data_config) train, val = get_one_dataset(conf, dataset_name) train_datasets.append(train) evals[dataset_name] = Subset(val, list(range(min(len(val), conf.eval_size)))) if conf.eval_size else val From 283df8ec84bae350c8c13e364807443c36ad071e Mon Sep 17 00:00:00 2001 From: Mark Worrall Date: Wed, 8 Feb 2023 20:49:25 +0000 Subject: [PATCH 02/54] Get working on multi-gpu --- model/supervised_finetuning/README.md | 128 +++++++++++------- .../supervised_finetuning/configs/config.yaml | 47 +++---- .../custom_datasets/qa_datasets.py | 5 +- .../custom_datasets/translation.py | 2 - model/supervised_finetuning/requirements.txt | 2 +- model/supervised_finetuning/trainer.py | 25 ++-- model/supervised_finetuning/utils.py | 78 +++++++---- 7 files changed, 167 insertions(+), 120 deletions(-) diff --git a/model/supervised_finetuning/README.md b/model/supervised_finetuning/README.md index d5b10e01..387e91e4 100644 --- a/model/supervised_finetuning/README.md +++ b/model/supervised_finetuning/README.md @@ -1,62 +1,18 @@ # Train using supervised examples -Requirements +## Requirements -``` -wandb -evaluate -datasets -transformers -torch -``` +`pip install -r requirements.txt` -Start training reward model +Start training SFT model ```bash -python trainer.py --configs defaults galactica-125 +python trainer.py --configs defaults galactica-125m ``` -## Dataset - -For now we only support webgpt and summary dataset from OpenAI. Once -open-asisstant dataset are available it will be added here. - -## Model - -Normally you should be able to add new models in configs/config.yml - -``` -your-model-name: - learning_rate: 2e-6 - model_name: - weight_decay: 0.01 - max_length: 812 - warmup_steps: 600 - gradient_checkpointing: false - gradient_accumulation_steps: 5 - per_device_train_batch_size: 4 - per_device_eval_batch_size: 4 -``` - -``` -python trainer.py --configs defaults your-model-name -``` - -However, if the model of your choice doesn't have pad_token, eos_token, -sep_token, you have to update utils.py `get_tokenizer` to use the right token. - -## Deepspeed support - -You can edit the configs/zero_config.json and use any stage you wish. The -current config uses zero-stage 3. For more details on how to setup the config -checkout [this page](https://www.deepspeed.ai/tutorials/zero/) - -Once you are satisfy with your deepzero config, you can add --deepspeed flag at -the end to trigger deepspeed - -``` -python trainer.py --configs defaults your-model-name --deepspeed -``` +For `wandb`: update the `entity` argument in `trainer.py`'s call to `wandb.init` +to be your weights and biases username per +[docs](https://docs.wandb.ai/ref/python/init). ## Dataset choices @@ -80,6 +36,74 @@ Currently only these languages are supported via prompt translation: ar,de,fr,en,it,nl,tr,ru,ms,ko,ja,zh ``` +## Dataset sub-sampling + +We can subsample the **training** data by passing either the `fraction` or +`size` argument in the `configs/config.yml` file. Don't forget the additional +colon ":" after the dataset name when doing this. + +Example: + +``` + datasets: + - webgpt: + fraction : 0.05 + - prompt_dialogue: + size : 500 + - adversarial_qa + - trivia_qa_nocontext +``` + +In this example, per epoch we will use: + +- A random 5% of `webgpt`; +- A random 500 examples from `prompt_dialogue`; +- All examples from datasets for which we don't specify the `fraction` or `size` + argument. + +In the above example, per epoch we'll use a different 5% from `webgpt` and a +different 500 examples from `prompt_dialogue`. + +This works with `torch.distributed`. + +## Model + +Normally you should be able to add new models in `configs/config.yml` + +``` +your-model-name: + learning_rate: 2e-6 + model_name: + weight_decay: 0.01 + max_length: 812 + warmup_steps: 600 + gradient_checkpointing: false + gradient_accumulation_steps: 5 + per_device_train_batch_size: 4 + per_device_eval_batch_size: 4 +``` + +``` +python trainer.py --configs defaults your-model-name +``` + +However, if the model of your choice doesn't have `pad_token`, `eos_token`, +`sep_token`, you have to update `get_tokenizer` in `utils.py` to use the right +token. + +## Deepspeed support + +You can edit the configs/zero_config.json and use any stage you wish. The +current config uses zero-stage 3. For more details on how to setup the config +checkout [this page](https://www.deepspeed.ai/tutorials/zero/). + +Once you are satisfy with your deepzero config, you can add --deepspeed flag at +the end to trigger deepspeed + +``` +python trainer.py --configs defaults your-model-name --deepspeed +``` + ## Results Experimental results in wandb @@ -87,7 +111,7 @@ Experimental results in wandb ## TODOS -- decide on a model +- Decide on a model - Merge utils etc with reward model - Casual Modelling for GPT-JT does not leverage the bidirectional mask for the prompt? (https://huggingface.co/togethercomputer/GPT-JT-6B-v1) diff --git a/model/supervised_finetuning/configs/config.yaml b/model/supervised_finetuning/configs/config.yaml index 925b6dda..289e49ad 100644 --- a/model/supervised_finetuning/configs/config.yaml +++ b/model/supervised_finetuning/configs/config.yaml @@ -16,32 +16,29 @@ defaults: eval_accumulation_steps: freeze_layer: datasets: - - webgpt: - fraction : 0.001 - - prompt_dialogue: - size : 10 - - squad_v2: - size : 10 - # - adversarial_qa - # - trivia_qa_nocontext - # - xsum - # - cnn_dailymail + - webgpt # - prompt_dialogue - # - multi_news - # - scitldr - # - soda - # - joke - # - gsm8k - # - dive_mt - # - wmt2019_zh-en - # - wmt2019_ru-en - # - wmt2019_de-en - # - ted_trans_nl-en - # - ted_trans_de-ja - # - instruct_tuning - # - wmt2019_de-en - # - samsum - # - soda_dialogue + - squad_v2 + - adversarial_qa + - trivia_qa_nocontext + - xsum + - cnn_dailymail + - prompt_dialogue + - multi_news + - scitldr + - soda + - joke + - gsm8k + - dive_mt + - wmt2019_zh-en + - wmt2019_ru-en + - wmt2019_de-en + - ted_trans_nl-en + - ted_trans_de-ja + - instruct_tuning + - wmt2019_de-en + - samsum + - soda_dialogue cache_dir: .cache loss_fn: CrossEntropyLoss eval_size: diff --git a/model/supervised_finetuning/custom_datasets/qa_datasets.py b/model/supervised_finetuning/custom_datasets/qa_datasets.py index 2c5c7ee2..206b679c 100644 --- a/model/supervised_finetuning/custom_datasets/qa_datasets.py +++ b/model/supervised_finetuning/custom_datasets/qa_datasets.py @@ -219,7 +219,7 @@ class SODA(Dataset): return pairs - def __init__(self, cache_dir, max_sample_size=10000, input_max_length=1024) -> None: + def __init__(self, cache_dir, input_max_length=1024) -> None: super().__init__() self.pairs = [] @@ -230,9 +230,6 @@ class SODA(Dataset): if len(prompt) < input_max_length: self.pairs.append((prompt, answer)) - if len(self.pairs) > max_sample_size: - break - def __len__(self): return len(self.pairs) diff --git a/model/supervised_finetuning/custom_datasets/translation.py b/model/supervised_finetuning/custom_datasets/translation.py index f9a71a8e..008de751 100644 --- a/model/supervised_finetuning/custom_datasets/translation.py +++ b/model/supervised_finetuning/custom_datasets/translation.py @@ -100,8 +100,6 @@ class WMT2019(TranslationPair): else: # translating in reverse direction source = random.choice(TRANSLATION_PROMPT[src]).format(row[tgt]) self.pairs.append((source, row[src])) - if len(self.pairs) > 100000: - break class DiveMT(TranslationPair): diff --git a/model/supervised_finetuning/requirements.txt b/model/supervised_finetuning/requirements.txt index efe6df89..95e5a472 100644 --- a/model/supervised_finetuning/requirements.txt +++ b/model/supervised_finetuning/requirements.txt @@ -4,7 +4,6 @@ datasets==2.8.0 deepspeed==0.7.7 evaluate==0.4.0 gdown -# mpi4py==3.1.4 nltk==3.8.1 numpy>=1.22.4 py7zr @@ -12,3 +11,4 @@ PyYAML>=6.0 scikit_learn==1.2.0 torch>=1.11.0 transformers==4.25.1 +wandb diff --git a/model/supervised_finetuning/trainer.py b/model/supervised_finetuning/trainer.py index 06ae39db..922be10b 100644 --- a/model/supervised_finetuning/trainer.py +++ b/model/supervised_finetuning/trainer.py @@ -8,8 +8,7 @@ import torch from torch import nn from transformers import PreTrainedModel, Trainer, TrainingArguments from transformers.training_args import OptimizerNames -from utils import (build_train_sampler, get_dataset, get_loss, get_metrics, - get_model, get_tokenizer, read_yamls) +from utils import PerDatasetSampler, get_dataset, get_loss, get_metrics, get_model, get_tokenizer, read_yamls def compute_metrics(eval_pred, preprocess_fns, metrics): @@ -92,20 +91,30 @@ class SFTTrainer(Trainer): return (loss, logits, labels) def get_train_dataloader(self): + """Inject custom data sampling behaviour into training loop""" if self.sampler is None: torch.utils.data.DataLoader( self.train_dataset, batch_size=self.args.per_device_train_batch_size, shuffle=True, - collate_fn=self.data_collator + collate_fn=self.data_collator, ) else: - return torch.utils.data.DataLoader( + dataloader = torch.utils.data.DataLoader( self.train_dataset, batch_size=self.args.per_device_train_batch_size, sampler=self.sampler, - collate_fn=self.data_collator + collate_fn=self.data_collator, ) + if torch.cuda.device_count() <= 1: + return dataloader + else: + # Not strictly necessary to use accelerate, currently just + # ensures batches are padded to be divisible by # devices + from accelerate import Accelerator + + accelerator = Accelerator() + return accelerator.prepare(dataloader) def _strtobool(x): @@ -160,7 +169,7 @@ if __name__ == "__main__": model = get_model(training_conf, tokenizer) train, evals, collate_fn = get_dataset(training_conf, tokenizer) - sampler = build_train_sampler(training_conf, train.datasets) + sampler = PerDatasetSampler.build_sampler_from_config(training_conf, train.datasets) metrics, preprocess_fns = get_metrics(training_conf, tokenizer) optimizer = OptimizerNames.ADAMW_BNB if training_conf.quantization else OptimizerNames.ADAMW_HF @@ -178,7 +187,7 @@ if __name__ == "__main__": learning_rate=float(training_conf.learning_rate), deepspeed="configs/zero_config.json" if training_conf.deepspeed else None, optim=optimizer, - # fp16=True, + fp16=True, local_rank=training_conf.local_rank, gradient_checkpointing=training_conf.gradient_checkpointing, gradient_accumulation_steps=training_conf.gradient_accumulation_steps, @@ -205,7 +214,7 @@ if __name__ == "__main__": entity="maw501", name=f"{training_conf.model_name}-{training_conf.log_dir}-finetuned", ) - + trainer = SFTTrainer( model=model, args=args, diff --git a/model/supervised_finetuning/utils.py b/model/supervised_finetuning/utils.py index 6d6b271a..c18cb380 100644 --- a/model/supervised_finetuning/utils.py +++ b/model/supervised_finetuning/utils.py @@ -1,11 +1,8 @@ -# from functools import partial +import random from pathlib import Path +from typing import List import evaluate -import random - -# import nltk -import numpy as np import transformers import yaml from custom_datasets import get_one_dataset @@ -18,32 +15,55 @@ from torch.utils.data import ConcatDataset, Subset from torch.utils.data.sampler import Sampler -class ClassSampler(Sampler): - """Sampler which returns a fixed number of samples per class, per epoch""" - def __init__(self, class_labels, class_sizes): - self.class_labels = class_labels - self.class_sizes = class_sizes +class PerDatasetSampler(Sampler): + """Sampler which returns a fixed number of samples per dataset, per epoch. + + Example: + + Dataset 1 has 10,000 examples and we want 200 per epoch + Dataset 2 has 500 examples and we want all 500 per epoch + + Epoch size will be 700 and every epoch we'll sample a different + 200 from dataset 1. + + Parameters + ---------- + dataset_sizes : List[int] + A list with the size of each dataset. + dataset_size_per_epoch : List[int] + How many examples to get from each dataset per epoch. + + Note: dataset_sizes & dataset_size_per_epoch must be in the same order. + Further the examples in the underlying torch.utils.data.Dataset + must per ordered as dataset_1, dataset_2, ..., dataset_n. This is fine + if we concatenate a bunch of datasets together + e.g. using torch.utils.data.ConcatDataset which is current behaviour. + """ + + def __init__(self, dataset_sizes: List[int], dataset_size_per_epoch: List[int]): + self.dataset_sizes = dataset_sizes + self.dataset_size_per_epoch = dataset_size_per_epoch + self.num_datasets = len(dataset_sizes) def __iter__(self): - out = [] - for i, _class in enumerate(np.unique(self.class_labels)): - class_idx = np.argwhere(self.class_labels == _class).flatten() - sampled_idx = random.sample(list(class_idx), int(self.class_sizes[i])) - out.extend(sampled_idx) - random.shuffle(out) - return iter(out) + epoch_idx = [] + n = 0 + for i in range(self.num_datasets): + sampled_idx = random.sample(range(n, self.dataset_sizes[i] + n), self.dataset_size_per_epoch[i]) + n += self.dataset_sizes[i] + epoch_idx.extend(sampled_idx) + random.shuffle(epoch_idx) + return iter(epoch_idx) def __len__(self): - return int(sum(self.class_sizes)) + return int(sum(self.dataset_size_per_epoch)) - -def build_train_sampler(training_conf, datasets): - train_sizes = [len(x) for x in datasets] - fractions = get_dataset_fractions(training_conf.datasets, train_sizes) - dataset_size_per_epoch = [int(size * frac) for size, frac in zip(train_sizes, fractions)] - dataset_labels = [[i] * d for i, d in zip(range(len(dataset_size_per_epoch)), dataset_size_per_epoch)] - dataset_labels = [i for s in dataset_labels for i in s] - return ClassSampler(dataset_labels, dataset_size_per_epoch) + @classmethod + def build_sampler_from_config(cls, training_conf, datasets): + dataset_sizes = [len(x) for x in datasets] + fractions = get_dataset_fractions(training_conf.datasets, dataset_sizes) + dataset_size_per_epoch = [int(size * frac) for size, frac in zip(dataset_sizes, fractions)] + return cls(dataset_sizes, dataset_size_per_epoch) def get_tokenizer(conf): @@ -157,13 +177,15 @@ def get_dataset_fractions(conf, dataset_sizes): dataset_name = get_dataset_name_from_data_config(data_config) if isinstance(data_config, dict): if "fraction" in data_config[dataset_name]: + if data_config[dataset_name]["fraction"] <= 0: + raise ValueError("Please specify fraction as a value between 0 < fraction <= 1") fractions.append(min(1, data_config[dataset_name]["fraction"])) elif "size" in data_config[dataset_name]: if data_config[dataset_name]["size"] > dataset_sizes[i]: - raise ValueError(f"Please specify a size smaller than number of examples ({dataset_sizes[i]})") + raise ValueError(f"Please specify a size smaller than number of examples: {dataset_sizes[i]:,.0f}") fractions.append(data_config[dataset_name]["size"] / dataset_sizes[i]) else: - raise ValueError("Please specify either fraction or size in config.yaml") + raise ValueError("Please specify either fraction or size in config.yaml. See README for instructions.") else: fractions.append(1) return fractions From 9faae250ce176c1025cf529003ceb3a5ef188a92 Mon Sep 17 00:00:00 2001 From: Mark Worrall Date: Wed, 8 Feb 2023 20:57:13 +0000 Subject: [PATCH 03/54] minor tidy-up --- model/supervised_finetuning/trainer.py | 3 +-- model/supervised_finetuning/utils.py | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/model/supervised_finetuning/trainer.py b/model/supervised_finetuning/trainer.py index 922be10b..72ae9f04 100644 --- a/model/supervised_finetuning/trainer.py +++ b/model/supervised_finetuning/trainer.py @@ -210,8 +210,7 @@ if __name__ == "__main__": wandb.init( project="supervised-finetuning", - # entity=training_conf.wandb_entity, - entity="maw501", + entity=training_conf.wandb_entity, name=f"{training_conf.model_name}-{training_conf.log_dir}-finetuned", ) diff --git a/model/supervised_finetuning/utils.py b/model/supervised_finetuning/utils.py index c18cb380..6c47bdb7 100644 --- a/model/supervised_finetuning/utils.py +++ b/model/supervised_finetuning/utils.py @@ -172,6 +172,7 @@ def get_dataset_name_from_data_config(data_config): def get_dataset_fractions(conf, dataset_sizes): + """Calculate fraction of each dataset to use per epoch when subsampling""" fractions = [] for i, data_config in enumerate(conf): dataset_name = get_dataset_name_from_data_config(data_config) From cc3891ed120c6bb31d9ea6e3a96b0018c3a5bd7b Mon Sep 17 00:00:00 2001 From: Richard Macarthy Date: Thu, 9 Feb 2023 02:45:03 +0000 Subject: [PATCH 04/54] Fix hydration issues side menu, move side_menu.json to common.json (#1327) Fixes #1326 This PR moves all json in side_menu.json to common.json. We have an issue with the side menu layout as it's a high level component and this causes hydration issues with SSR when global namespaces are not passed by default. --- website/public/locales/ar/common.json | 9 +++++++++ website/public/locales/ar/side_menu.json | 12 ------------ website/public/locales/ca/common.json | 9 +++++++++ website/public/locales/ca/side_menu.json | 12 ------------ website/public/locales/de/common.json | 9 +++++++++ website/public/locales/de/side_menu.json | 12 ------------ website/public/locales/en/common.json | 11 +++++++++++ website/public/locales/en/side_menu.json | 13 ------------- website/public/locales/es/common.json | 9 +++++++++ website/public/locales/es/side_menu.json | 12 ------------ website/public/locales/fr/common.json | 9 +++++++++ website/public/locales/fr/side_menu.json | 12 ------------ website/public/locales/hu/common.json | 9 +++++++++ website/public/locales/hu/side_menu.json | 12 ------------ website/public/locales/it/common.json | 9 +++++++++ website/public/locales/it/side_menu.json | 12 ------------ website/public/locales/ko/common.json | 9 +++++++++ website/public/locales/ko/side_menu.json | 12 ------------ website/public/locales/pl/common.json | 9 +++++++++ website/public/locales/pl/side_menu.json | 12 ------------ website/public/locales/pt-BR/common.json | 9 +++++++++ website/public/locales/pt-BR/side_menu.json | 12 ------------ website/public/locales/ru/common.json | 11 ++++++++++- website/public/locales/ru/side_menu.json | 12 ------------ website/public/locales/tr/common.json | 9 +++++++++ website/public/locales/tr/side_menu.json | 12 ------------ website/public/locales/uk-UA/common.json | 11 ++++++++++- website/public/locales/uk-UA/side_menu.json | 12 ------------ website/public/locales/vi/common.json | 9 +++++++++ website/public/locales/vi/side_menu.json | 12 ------------ website/public/locales/zh/common.json | 9 +++++++++ website/public/locales/zh/side_menu.json | 12 ------------ website/src/components/SideMenu.tsx | 2 +- website/types/i18next.d.ts | 2 -- 34 files changed, 149 insertions(+), 198 deletions(-) delete mode 100644 website/public/locales/ar/side_menu.json delete mode 100644 website/public/locales/ca/side_menu.json delete mode 100644 website/public/locales/de/side_menu.json delete mode 100644 website/public/locales/en/side_menu.json delete mode 100644 website/public/locales/es/side_menu.json delete mode 100644 website/public/locales/fr/side_menu.json delete mode 100644 website/public/locales/hu/side_menu.json delete mode 100644 website/public/locales/it/side_menu.json delete mode 100644 website/public/locales/ko/side_menu.json delete mode 100644 website/public/locales/pl/side_menu.json delete mode 100644 website/public/locales/pt-BR/side_menu.json delete mode 100644 website/public/locales/ru/side_menu.json delete mode 100644 website/public/locales/tr/side_menu.json delete mode 100644 website/public/locales/uk-UA/side_menu.json delete mode 100644 website/public/locales/vi/side_menu.json delete mode 100644 website/public/locales/zh/side_menu.json diff --git a/website/public/locales/ar/common.json b/website/public/locales/ar/common.json index b89cafe8..b316033a 100644 --- a/website/public/locales/ar/common.json +++ b/website/public/locales/ar/common.json @@ -6,22 +6,31 @@ "conversational": "ذكاء تحدثي للجميع.", "copied": "Copied", "dark_mode": "الوضع الداكن", + "dashboard_home": "الصفحة الرئيسية للإحصائيات", "dashboard": "لوحة التحكم", "delete": "حذف", "discord": "ديسكورد", "docs": "وثائق", "github": "جيت هوب (github)", + "leaderboard": "جدول الأوائل", "legal": "قانوني", "light_mode": "الوضع المضيء", "loading": "جار التحميل...", + "messages_dashboard": "لوحة تحكم الرسائل", + "messages": "رسائل", "more_information": "مزيد من المعلومات", "no": "لا", "privacy_policy": "سياسة الخصوصية", "report_a_bug": "إبلاغ عن خطأ", "sign_in": "تسجيل الدخول", "sign_out": "تسجيل الخروج", + "status_dashboard": "لوحة تحكم الحالة", + "status": "الحالة", "success": "Success", "terms_of_service": "شروط الخدمة", "title": "Open Assistant (المساعد المفتوح)", + "user_leaderboard": "جدول الأوائل للمستخدمين", + "users_dashboard": "لوحة تحكم المستخدمين", + "users": "المستخدمون", "yes": "نعم" } diff --git a/website/public/locales/ar/side_menu.json b/website/public/locales/ar/side_menu.json deleted file mode 100644 index 4f7edcae..00000000 --- a/website/public/locales/ar/side_menu.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dashboard": "لوحة التحكم", - "dashboard_home": "الصفحة الرئيسية للإحصائيات", - "leaderboard": "جدول الأوائل", - "messages": "رسائل", - "messages_dashboard": "لوحة تحكم الرسائل", - "status": "الحالة", - "status_dashboard": "لوحة تحكم الحالة", - "user_leaderboard": "جدول الأوائل للمستخدمين", - "users": "المستخدمون", - "users_dashboard": "لوحة تحكم المستخدمين" -} diff --git a/website/public/locales/ca/common.json b/website/public/locales/ca/common.json index b08d65b2..23433c15 100644 --- a/website/public/locales/ca/common.json +++ b/website/public/locales/ca/common.json @@ -6,14 +6,18 @@ "conversational": "AI conversacional per a tothom.", "copied": "Copiat", "dark_mode": "Mode fosc", + "dashboard_home": "Panell principal", "dashboard": "Panell principal", "delete": "Esborrar", "discord": "Discord", "docs": "Documentació", "github": "GitHub", + "leaderboard": "Classificacions", "legal": "Legal", "light_mode": "Mode clar", "loading": "Carregant...", + "messages_dashboard": "Taulell de missatges", + "messages": "Missatges", "more_information": "Més informació", "no": "No", "privacy_policy": "Política de privacitat", @@ -21,7 +25,12 @@ "sign_in": "Iniciar sessió", "sign_out": "Tancar sessió", "success": "Èxit", + "status_dashboard": "Taulell d'estat", + "status": "Estat", "terms_of_service": "Termes de servei", "title": "Open Assistant", + "user_leaderboard": "Classificació d'usuaris", + "users_dashboard": "Taulell d'usuaris", + "users": "Usuaris", "yes": "Sí" } diff --git a/website/public/locales/ca/side_menu.json b/website/public/locales/ca/side_menu.json deleted file mode 100644 index 84e079d7..00000000 --- a/website/public/locales/ca/side_menu.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dashboard": "Panell principal", - "dashboard_home": "Panell principal", - "leaderboard": "Classificacions", - "messages": "Missatges", - "messages_dashboard": "Taulell de missatges", - "status": "Estat", - "status_dashboard": "Taulell d'estat", - "user_leaderboard": "Classificació d'usuaris", - "users": "Usuaris", - "users_dashboard": "Taulell d'usuaris" -} diff --git a/website/public/locales/de/common.json b/website/public/locales/de/common.json index d401f4cb..655745de 100644 --- a/website/public/locales/de/common.json +++ b/website/public/locales/de/common.json @@ -6,22 +6,31 @@ "conversational": "Konversations-KI für alle.", "copied": "Kopiert", "dark_mode": "Dunkler Modus", + "dashboard_home": "Dashboard Home", "dashboard": "Dashboard", "delete": "Löschen", "discord": "Discord", "docs": "Doku", "github": "GitHub", + "leaderboard": "Leaderboard", "legal": "Rechtliches", "light_mode": "Heller Modus", "loading": "Wird geladen...", + "messages_dashboard": "Messages Dashboard", + "messages": "Nachrichten", "more_information": "Weitere Informationen", "no": "Nein", "privacy_policy": "Datenschutz-Bestimmungen", "report_a_bug": "Einen Fehler melden", "sign_in": "Anmelden", "sign_out": "Abmelden", + "status_dashboard": "Status Dashboard", + "status": "Status", "success": "Erfolg", "terms_of_service": "Nutzungsbedingungen", "title": "Open Assistant", + "user_leaderboard": "User Leaderboard", + "users_dashboard": "Users Dashboard", + "users": "Users", "yes": "Ja" } diff --git a/website/public/locales/de/side_menu.json b/website/public/locales/de/side_menu.json deleted file mode 100644 index c17b475a..00000000 --- a/website/public/locales/de/side_menu.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dashboard": "Dashboard", - "dashboard_home": "Dashboard Home", - "leaderboard": "Leaderboard", - "messages": "Nachrichten", - "messages_dashboard": "Messages Dashboard", - "status": "Status", - "status_dashboard": "Status Dashboard", - "user_leaderboard": "User Leaderboard", - "users": "Users", - "users_dashboard": "Users Dashboard" -} diff --git a/website/public/locales/en/common.json b/website/public/locales/en/common.json index b964b26a..08ae1ee4 100644 --- a/website/public/locales/en/common.json +++ b/website/public/locales/en/common.json @@ -6,22 +6,33 @@ "conversational": "Conversational AI for everyone.", "copied": "Copied", "dark_mode": "Dark Mode", + "dashboard_home": "Dashboard Home", "dashboard": "Dashboard", "delete": "Delete", "discord": "Discord", "docs": "Docs", "github": "GitHub", + "leaderboard": "Leaderboard", "legal": "Legal", "light_mode": "Light Mode", "loading": "Loading...", + "messages_dashboard": "Messages Dashboard", + "messages": "Messages", "more_information": "More Information", "no": "No", + "parameters": "Parameters", "privacy_policy": "Privacy Policy", "report_a_bug": "Report a Bug", "sign_in": "Sign In", "sign_out": "Sign Out", + "status": "Status", + "status_dashboard": "Status Dashboard", "success": "Success", "terms_of_service": "Terms of Service", "title": "Open Assistant", + "trollboard": "Trollboard", + "user_leaderboard": "User Leaderboard", + "users_dashboard": "Users Dashboard", + "users": "Users", "yes": "Yes" } diff --git a/website/public/locales/en/side_menu.json b/website/public/locales/en/side_menu.json deleted file mode 100644 index cbbb3fad..00000000 --- a/website/public/locales/en/side_menu.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "dashboard": "Dashboard", - "dashboard_home": "Dashboard Home", - "messages": "Messages", - "messages_dashboard": "Messages Dashboard", - "leaderboard": "Leaderboard", - "user_leaderboard": "User Leaderboard", - "users": "Users", - "users_dashboard": "Users Dashboard", - "status": "Status", - "status_dashboard": "Status Dashboard", - "trollboard": "Trollboard" -} diff --git a/website/public/locales/es/common.json b/website/public/locales/es/common.json index eac24039..23bd5955 100644 --- a/website/public/locales/es/common.json +++ b/website/public/locales/es/common.json @@ -6,22 +6,31 @@ "conversational": "IA conversacional para todos.", "copied": "Copiado", "dark_mode": "Modo oscuro", + "dashboard_home": "Panel principal", "dashboard": "Panel principal", "delete": "Borrar", "discord": "Discord", "docs": "Documentación", "github": "GitHub", + "leaderboard": "Clasificaciones", "legal": "Legal", "light_mode": "Modo claro", "loading": "Cargando...", + "messages_dashboard": "Tablón de mensajes", + "messages": "Mensajes", "more_information": "Más información", "no": "No", "privacy_policy": "Política de privacidad", "report_a_bug": "Informar de un error", "sign_in": "Iniciar sesión", "sign_out": "Cerrar sesión", + "status_dashboard": "Tablón de estado", + "status": "Estado", "success": "Éxito", "terms_of_service": "Términos de servicio", "title": "Open Assistant", + "user_leaderboard": "Clasificación de usuarios", + "users_dashboard": "Tablón de usuarios", + "users": "Usuarios", "yes": "Sí" } diff --git a/website/public/locales/es/side_menu.json b/website/public/locales/es/side_menu.json deleted file mode 100644 index 080fb902..00000000 --- a/website/public/locales/es/side_menu.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dashboard": "Panel principal", - "dashboard_home": "Panel principal", - "leaderboard": "Clasificaciones", - "messages": "Mensajes", - "messages_dashboard": "Tablón de mensajes", - "status": "Estado", - "status_dashboard": "Tablón de estado", - "user_leaderboard": "Clasificación de usuarios", - "users": "Usuarios", - "users_dashboard": "Tablón de usuarios" -} diff --git a/website/public/locales/fr/common.json b/website/public/locales/fr/common.json index 66c882c9..d05a63b9 100644 --- a/website/public/locales/fr/common.json +++ b/website/public/locales/fr/common.json @@ -6,22 +6,31 @@ "conversational": "IA conversationnelle pour tout le monde.", "copied": "Copied", "dark_mode": "Mode sombre", + "dashboard_home": "Accueil du tableau de bord", "dashboard": "Tableau de bord", "delete": "Supprimer", "discord": "Discord", "docs": "Docs", "github": "GitHub", + "leaderboard": "Classement", "legal": "Légal", "light_mode": "Mode clair", "loading": "Chargement en cours...", + "messages_dashboard": "Tableau de bord des messages", + "messages": "Messages", "more_information": "Plus d'informations", "no": "Non", "privacy_policy": "Politique de confidentialité", "report_a_bug": "Signaler un bug", "sign_in": "Se connecter", "sign_out": "Se déconnecter", + "status_dashboard": "Tableau de bord de statut", + "status": "Statut", "success": "Success", "terms_of_service": "Conditions d'utilisation", "title": "Open Assistant", + "user_leaderboard": "Classement des utilisateurs", + "users_dashboard": "Tableau de bord des utilisateurs", + "users": "Utilisateurs", "yes": "Oui" } diff --git a/website/public/locales/fr/side_menu.json b/website/public/locales/fr/side_menu.json deleted file mode 100644 index 87f62a5e..00000000 --- a/website/public/locales/fr/side_menu.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dashboard": "Tableau de bord", - "dashboard_home": "Accueil du tableau de bord", - "leaderboard": "Classement", - "messages": "Messages", - "messages_dashboard": "Tableau de bord des messages", - "status": "Statut", - "status_dashboard": "Tableau de bord de statut", - "user_leaderboard": "Classement des utilisateurs", - "users": "Utilisateurs", - "users_dashboard": "Tableau de bord des utilisateurs" -} diff --git a/website/public/locales/hu/common.json b/website/public/locales/hu/common.json index f0cb71bb..9baa036e 100644 --- a/website/public/locales/hu/common.json +++ b/website/public/locales/hu/common.json @@ -6,22 +6,31 @@ "conversational": "Társalgási MI Mindenkinek.", "copied": "Copied", "dark_mode": "Dark Mode", + "dashboard_home": "Dashboard Home", "dashboard": "Irányítópult", "delete": "Delete", "discord": "Discord", "docs": "Leírás", "github": "GitHub", + "leaderboard": "Leaderboard", "legal": "Jogi", "light_mode": "Light Mode", "loading": "Betöltés...", + "messages_dashboard": "Messages Dashboard", + "messages": "Messages", "more_information": "További információ", "no": "Nem", "privacy_policy": "Adatvédelem", "report_a_bug": "Hibabejelentés", "sign_in": "Bejelentkezés", "sign_out": "Kijelentkezés", + "status_dashboard": "Status Dashboard", + "status": "Status", "success": "Success", "terms_of_service": "Felhasználási feltételek", "title": "Open Assistant", + "user_leaderboard": "User Leaderboard", + "users_dashboard": "Users Dashboard", + "users": "Users", "yes": "Igen" } diff --git a/website/public/locales/hu/side_menu.json b/website/public/locales/hu/side_menu.json deleted file mode 100644 index 293112f4..00000000 --- a/website/public/locales/hu/side_menu.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dashboard": "Dashboard", - "dashboard_home": "Dashboard Home", - "leaderboard": "Leaderboard", - "messages": "Messages", - "messages_dashboard": "Messages Dashboard", - "status": "Status", - "status_dashboard": "Status Dashboard", - "user_leaderboard": "User Leaderboard", - "users": "Users", - "users_dashboard": "Users Dashboard" -} diff --git a/website/public/locales/it/common.json b/website/public/locales/it/common.json index ad6b45be..32204ed2 100644 --- a/website/public/locales/it/common.json +++ b/website/public/locales/it/common.json @@ -6,22 +6,31 @@ "conversational": "I.A. di conversazione per tutti.", "copied": "Copiato", "dark_mode": "Modalità scura", + "dashboard_home": "Schermata iniziale", "dashboard": "Pannello di controllo", "delete": "Cancella", "discord": "Discord", "docs": "Documenti", "github": "GitHub", + "leaderboard": "Classifica", "legal": "Legale", "light_mode": "Modalità chiara", "loading": "Caricando...", + "messages_dashboard": "Pannello di controllo dei messaggi", + "messages": "Messaggi", "more_information": "Maggiori Informazioni", "no": "No", "privacy_policy": "Politica sulla Privacy", "report_a_bug": "Segnala un problema", "sign_in": "Sign In", "sign_out": "Esci", + "status_dashboard": "Pannello di controllo dello stato", + "status": "Stato", "success": "Successo", "terms_of_service": "Termini di Servizio", "title": "Open Assistant", + "user_leaderboard": "Classifica dell'utente", + "users_dashboard": "Pannello di controllo degli utenti", + "users": "Utenti", "yes": "Si" } diff --git a/website/public/locales/it/side_menu.json b/website/public/locales/it/side_menu.json deleted file mode 100644 index 9bb8b7fb..00000000 --- a/website/public/locales/it/side_menu.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dashboard": "Pannello di controllo", - "dashboard_home": "Schermata iniziale", - "leaderboard": "Classifica", - "messages": "Messaggi", - "messages_dashboard": "Pannello di controllo dei messaggi", - "status": "Stato", - "status_dashboard": "Pannello di controllo dello stato", - "user_leaderboard": "Classifica dell'utente", - "users": "Utenti", - "users_dashboard": "Pannello di controllo degli utenti" -} diff --git a/website/public/locales/ko/common.json b/website/public/locales/ko/common.json index b7029019..491f8dbd 100644 --- a/website/public/locales/ko/common.json +++ b/website/public/locales/ko/common.json @@ -6,22 +6,31 @@ "conversational": "모두를 위한 대화형 AI.", "copied": "Copied", "dark_mode": "다크 모드", + "dashboard_home": "대시보드 홈", "dashboard": "대시보드", "delete": "삭제", "discord": "Discord", "docs": "문서", "github": "GitHub", + "leaderboard": "리더보드", "legal": "Legal", "light_mode": "라이트 모드", "loading": "로딩중...", + "messages_dashboard": "메세지 대시보드", + "messages": "메세지", "more_information": "추가 정보", "no": "아니오", "privacy_policy": "개인정보보호 정책", "report_a_bug": "버그신고", "sign_in": "Sign In", "sign_out": "Sign Out", + "status_dashboard": "상태 대시보드", + "status": "상태", "success": "Success", "terms_of_service": "서비스 약관", "title": "오픈 어시스턴트", + "user_leaderboard": "사용자 리더보드", + "users_dashboard": "사용자 대시보드", + "users": "사용자", "yes": "예" } diff --git a/website/public/locales/ko/side_menu.json b/website/public/locales/ko/side_menu.json deleted file mode 100644 index 99b43380..00000000 --- a/website/public/locales/ko/side_menu.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dashboard": "대시보드", - "dashboard_home": "대시보드 홈", - "leaderboard": "리더보드", - "messages": "메세지", - "messages_dashboard": "메세지 대시보드", - "status": "상태", - "status_dashboard": "상태 대시보드", - "user_leaderboard": "사용자 리더보드", - "users": "사용자", - "users_dashboard": "사용자 대시보드" -} diff --git a/website/public/locales/pl/common.json b/website/public/locales/pl/common.json index 01bca692..cb2db217 100644 --- a/website/public/locales/pl/common.json +++ b/website/public/locales/pl/common.json @@ -6,22 +6,31 @@ "conversational": "Konwersacyjna SI dla każdego.", "copied": "Skopiowano", "dark_mode": "Tryb ciemny", + "dashboard_home": "Strona Główna Panelu", "dashboard": "Panel", "delete": "Usuń", "discord": "Discord", "docs": "Dokumentacja", "github": "GitHub", + "leaderboard": "Ranking", "legal": "Prawa", "light_mode": "Tryb jasny", "loading": "Wczytywanie...", + "messages_dashboard": "Strona Główna Wiadomości", + "messages": "Wiadomości", "more_information": "Więcej Informacji", "no": "Nie", "privacy_policy": "Polityka Prywatności", "report_a_bug": "Zgłoś Błąd", "sign_in": "Zaloguj Się", "sign_out": "Wyloguj Się", + "status_dashboard": "Panel Statusu", + "status": "Status", "success": "Sukces", "terms_of_service": "Warunki Usługi", "title": "Open Assistant", + "user_leaderboard": "Ranking Użytkowników", + "users_dashboard": "Panel Użytkownika", + "users": "Użytkownicy", "yes": "Tak" } diff --git a/website/public/locales/pl/side_menu.json b/website/public/locales/pl/side_menu.json deleted file mode 100644 index f352bd9f..00000000 --- a/website/public/locales/pl/side_menu.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dashboard": "Panel", - "dashboard_home": "Strona Główna Panelu", - "messages": "Wiadomości", - "messages_dashboard": "Strona Główna Wiadomości", - "leaderboard": "Ranking", - "user_leaderboard": "Ranking Użytkowników", - "users": "Użytkownicy", - "users_dashboard": "Panel Użytkownika", - "status": "Status", - "status_dashboard": "Panel Statusu" -} diff --git a/website/public/locales/pt-BR/common.json b/website/public/locales/pt-BR/common.json index 0e33ed21..cfa5a25f 100644 --- a/website/public/locales/pt-BR/common.json +++ b/website/public/locales/pt-BR/common.json @@ -6,22 +6,31 @@ "conversational": "IA conversacional para todos.", "copied": "Copiado", "dark_mode": "Tema Escuro", + "dashboard_home": "Página principal", "dashboard": "Painel", "delete": "Deletar", "discord": "Discord", "docs": "Documentação", "github": "GitHub", + "leaderboard": "Leaderboard", "legal": "Legal", "light_mode": "Tema Claro", "loading": "Carregando...", + "messages_dashboard": "Painel de mensagens", + "messages": "Mensagens", "more_information": "Mais informações...", "no": "Não", "privacy_policy": "Política de Privacidade", "report_a_bug": "Reportar um erro", "sign_in": "Entrar", "sign_out": "Sair", + "status_dashboard": "Painel de status", + "status": "Status", "success": "Sucesso", "terms_of_service": "Termos de serviço", "title": "Open Assistant", + "user_leaderboard": "Leaderboard dos usuários", + "users_dashboard": "Painel de controle de usuários", + "users": "Usuários", "yes": "Sim" } diff --git a/website/public/locales/pt-BR/side_menu.json b/website/public/locales/pt-BR/side_menu.json deleted file mode 100644 index 78b01d57..00000000 --- a/website/public/locales/pt-BR/side_menu.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dashboard": "Painel", - "dashboard_home": "Página principal", - "leaderboard": "Leaderboard", - "messages": "Mensagens", - "messages_dashboard": "Painel de mensagens", - "status": "Status", - "status_dashboard": "Painel de status", - "user_leaderboard": "Leaderboard dos usuários", - "users": "Usuários", - "users_dashboard": "Painel de controle de usuários" -} diff --git a/website/public/locales/ru/common.json b/website/public/locales/ru/common.json index 941deeb1..7fbf86ee 100644 --- a/website/public/locales/ru/common.json +++ b/website/public/locales/ru/common.json @@ -6,22 +6,31 @@ "conversational": "Разговорный ИИ для каждого.", "copied": "Скопировано", "dark_mode": "Темная тема", + "dashboard_home": "Главная страница", "dashboard": "Главная", "delete": "Удалить", "discord": "Discord", "docs": "Документация", "github": "GitHub", + "leaderboard": "Рейтинг", "legal": "Legal", "light_mode": "Светлая тема", "loading": "Загрузка...", + "messages_dashboard": "Панель просмотра сообщений", + "messages": "Сообщения", "more_information": "Больше...", "no": "Нет", "privacy_policy": "Политика конфиденциальности", "report_a_bug": "Сообщить об ошибке", "sign_in": "Вход", "sign_out": "Выйти из аккаунта", - "success": "Успешно", + "status_dashboard": "Панель состояния системы", + "status": "Статус", + "success": "Success", "terms_of_service": "Пользовательское Соглашение", "title": "Open Assistant", + "user_leaderboard": "Таблица лидеров", + "users_dashboard": "Панель управления пользователями", + "users": "Пользователи", "yes": "Да" } diff --git a/website/public/locales/ru/side_menu.json b/website/public/locales/ru/side_menu.json deleted file mode 100644 index e72ef732..00000000 --- a/website/public/locales/ru/side_menu.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dashboard": "Главная", - "dashboard_home": "Главная страница", - "leaderboard": "Рейтинг", - "messages": "Сообщения", - "messages_dashboard": "Панель просмотра сообщений", - "status": "Статус", - "status_dashboard": "Панель состояния системы", - "user_leaderboard": "Таблица лидеров", - "users": "Пользователи", - "users_dashboard": "Панель управления пользователями" -} diff --git a/website/public/locales/tr/common.json b/website/public/locales/tr/common.json index bd220d7c..5499c97c 100644 --- a/website/public/locales/tr/common.json +++ b/website/public/locales/tr/common.json @@ -6,22 +6,31 @@ "conversational": "Herkes için etkileşimli AI", "copied": "Kopyalandı", "dark_mode": "Karanlık Mod", + "dashboard_home": "Kontrol Paneli Ana Sayfa", "dashboard": "Kontrol Paneli", "delete": "Sil", "discord": "Discord", "docs": "Dokümantasyon", "github": "GitHub", + "leaderboard": "Lider Tablosu", "legal": "Yasal", "light_mode": "Açık Mod", "loading": "Yükleniyor...", + "messages_dashboard": "Mesaj Kontrol Paneli", + "messages": "Mesajlar", "more_information": "Daha Fazla Bilgi", "no": "No", "privacy_policy": "Gizlilik Politikası", "report_a_bug": "Hata Bildir", "sign_in": "Giriş Yap", "sign_out": "Çıkış Yap", + "status_dashboard": "Durum Kontrol Paneli", + "status": "Durum", "success": "Başarılı", "terms_of_service": "Kullanım Şartları", "title": "Open Assistant", + "user_leaderboard": "Kullanıcı Lider Tablosu", + "users_dashboard": "Kullanıcı Kontrol Paneli", + "users": "Kullanıcılar", "yes": "Evet" } diff --git a/website/public/locales/tr/side_menu.json b/website/public/locales/tr/side_menu.json deleted file mode 100644 index 8add2136..00000000 --- a/website/public/locales/tr/side_menu.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dashboard": "Kontrol Paneli", - "dashboard_home": "Kontrol Paneli Ana Sayfa", - "leaderboard": "Lider Tablosu", - "messages": "Mesajlar", - "messages_dashboard": "Mesaj Kontrol Paneli", - "status": "Durum", - "status_dashboard": "Durum Kontrol Paneli", - "user_leaderboard": "Kullanıcı Lider Tablosu", - "users": "Kullanıcılar", - "users_dashboard": "Kullanıcı Kontrol Paneli" -} diff --git a/website/public/locales/uk-UA/common.json b/website/public/locales/uk-UA/common.json index 8f8829ea..4904b4e4 100644 --- a/website/public/locales/uk-UA/common.json +++ b/website/public/locales/uk-UA/common.json @@ -6,22 +6,31 @@ "conversational": "Розмовний ШІ для кожного.", "copied": "Скопійовано", "dark_mode": "Темний режим", - "dashboard": "Головна панель", + "dashboard_home": "Головна панель", + "dashboard": "Головна", "delete": "Видалити", "discord": "Discord", "docs": "Документація", "github": "GitHub", + "leaderboard": "Рейтинг лідерів", "legal": "Юридична інформація", "light_mode": "Світлий режим", "loading": "Завантаження...", + "messages_dashboard": "Панель повідомлень", + "messages": "Повідомлення", "more_information": "Більше інформації", "no": "Ні", "privacy_policy": "Політика конфіденційності", "report_a_bug": "Сповістити про помилку", "sign_in": "Війти", "sign_out": "Вийти", + "status_dashboard": "Панель статусів", + "status": "Статус", "success": "Успіх", "terms_of_service": "Умови використання", "title": "Open Assistant", + "user_leaderboard": "User Leaderboard", + "users_dashboard": "Панель користувачів", + "users": "Користувачі", "yes": "Так" } diff --git a/website/public/locales/uk-UA/side_menu.json b/website/public/locales/uk-UA/side_menu.json deleted file mode 100644 index 4111a0c7..00000000 --- a/website/public/locales/uk-UA/side_menu.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dashboard": "Головна", - "dashboard_home": "Головна панель", - "leaderboard": "Рейтинг лідерів", - "messages": "Повідомлення", - "messages_dashboard": "Панель повідомлень", - "status": "Статус", - "status_dashboard": "Панель статусів", - "user_leaderboard": "User Leaderboard", - "users": "Користувачі", - "users_dashboard": "Панель користувачів" -} diff --git a/website/public/locales/vi/common.json b/website/public/locales/vi/common.json index 9896e4c2..71309549 100644 --- a/website/public/locales/vi/common.json +++ b/website/public/locales/vi/common.json @@ -6,22 +6,31 @@ "conversational": "Chatbot AI cho tất cả mọi người", "copied": "Copied", "dark_mode": "Giao diện tối", + "dashboard_home": "Trang chính", "dashboard": "Trang chính", "delete": "Xoá", "discord": "Discord", "docs": "Hướng dẫn", "github": "GitHub", + "leaderboard": "Bảng xếp hạng", "legal": "Luật lệ", "light_mode": "Giao diện sáng", "loading": "Đang tải...", + "messages_dashboard": "Bảng xếp hạng tin nhắn", + "messages": "Tin nhắn", "more_information": "Xem thêm", "no": "Không", "privacy_policy": "Chính sách bảo mật", "report_a_bug": "Báo lỗi", "sign_in": "Đăng nhập", "sign_out": "Đăng xuất", + "status_dashboard": "Trang hiện tình trạng", + "status": "Tình trạng", "success": "Success", "terms_of_service": "Điều khoản sử dụng", "title": "Open Assistant", + "user_leaderboard": "Bảng xếp hạng người dùng", + "users_dashboard": "Trang về người dùng", + "users": "Người dùng", "yes": "Có" } diff --git a/website/public/locales/vi/side_menu.json b/website/public/locales/vi/side_menu.json deleted file mode 100644 index 6b06846f..00000000 --- a/website/public/locales/vi/side_menu.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dashboard": "Trang chính", - "dashboard_home": "Trang chính", - "leaderboard": "Bảng xếp hạng", - "messages": "Tin nhắn", - "messages_dashboard": "Bảng xếp hạng tin nhắn", - "status": "Tình trạng", - "status_dashboard": "Trang hiện tình trạng", - "user_leaderboard": "Bảng xếp hạng người dùng", - "users": "Người dùng", - "users_dashboard": "Trang về người dùng" -} diff --git a/website/public/locales/zh/common.json b/website/public/locales/zh/common.json index bba05485..3776f825 100644 --- a/website/public/locales/zh/common.json +++ b/website/public/locales/zh/common.json @@ -6,22 +6,31 @@ "conversational": "每个人的对话式人工智能。", "copied": "已复制", "dark_mode": "深色模式", + "dashboard_home": "概览首页", "dashboard": "概览", "delete": "删除", "discord": "Discord", "docs": "文档", "github": "GitHub", + "leaderboard": "排行榜", "legal": "法律信息", "light_mode": "浅色模式", "loading": "载入中...", + "messages_dashboard": "信息概览", + "messages": "信息", "more_information": "更多信息", "no": "否", "privacy_policy": "隐私政策", "report_a_bug": "报告问题", "sign_in": "登入", "sign_out": "登出", + "status_dashboard": "状态概览", + "status": "状态", "success": "成功", "terms_of_service": "服务条款", "title": "Open Assistant", + "user_leaderboard": "用户排行榜", + "users_dashboard": "用户概览", + "users": "用户", "yes": "是" } diff --git a/website/public/locales/zh/side_menu.json b/website/public/locales/zh/side_menu.json deleted file mode 100644 index fbb69bd1..00000000 --- a/website/public/locales/zh/side_menu.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dashboard": "概览", - "dashboard_home": "概览首页", - "messages": "信息", - "messages_dashboard": "信息概览", - "leaderboard": "排行榜", - "user_leaderboard": "用户排行榜", - "users": "用户", - "users_dashboard": "用户概览", - "status": "状态", - "status_dashboard": "状态概览" -} diff --git a/website/src/components/SideMenu.tsx b/website/src/components/SideMenu.tsx index 7ae67612..6988d1fc 100644 --- a/website/src/components/SideMenu.tsx +++ b/website/src/components/SideMenu.tsx @@ -17,7 +17,7 @@ export interface SideMenuProps { export function SideMenu(props: SideMenuProps) { const router = useRouter(); - const { t } = useTranslation(["side_menu", "common"]); + const { t } = useTranslation(); return (
diff --git a/website/types/i18next.d.ts b/website/types/i18next.d.ts index 05111279..8b7a0e24 100644 --- a/website/types/i18next.d.ts +++ b/website/types/i18next.d.ts @@ -4,7 +4,6 @@ import type index from "public/locales/en/index.json"; import type labelling from "public/locales/en/labelling.json"; import type leaderboard from "public/locales/en/leaderboard.json"; import type message from "public/locales/en/message.json"; -import type side_menu from "public/locales/en/side_menu.json"; import type tasks from "public/locales/en/tasks.json"; import type tos from "public/locales/en/tos.json"; @@ -18,7 +17,6 @@ declare module "i18next" { tasks: typeof tasks; message: typeof message; labelling: typeof labelling; - side_menu: typeof side_menu; tos: typeof tos; }; } From aded93a1e7d5dab5f19982fce53a31bb5ae8b990 Mon Sep 17 00:00:00 2001 From: chronikum <34622984+chronikum@users.noreply.github.com> Date: Thu, 9 Feb 2023 03:49:08 +0100 Subject: [PATCH 05/54] Translating all german keys not yet translated to german (#1360) I translated not yet translated keys and fixed one case where we used informal speech, because everywhere else formal speech is being used. closes #1230 --- website/public/locales/de/dashboard.json | 2 +- website/public/locales/de/labelling.json | 2 +- website/public/locales/de/message.json | 10 +++++----- website/public/locales/de/tasks.json | 2 +- website/public/locales/de/tos.json | 8 ++++---- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/website/public/locales/de/dashboard.json b/website/public/locales/de/dashboard.json index b418eaaa..66e86532 100644 --- a/website/public/locales/de/dashboard.json +++ b/website/public/locales/de/dashboard.json @@ -3,6 +3,6 @@ "dashboard": "Dashboard", "evaluate": "Auswerten", "go": "Los", - "grab_a_task": "Schnapp dir eine Aufgabe!", + "grab_a_task": "Schnappen Sie sich eine Aufgabe!", "label": "Label" } diff --git a/website/public/locales/de/labelling.json b/website/public/locales/de/labelling.json index 6569976c..19854d06 100644 --- a/website/public/locales/de/labelling.json +++ b/website/public/locales/de/labelling.json @@ -19,6 +19,6 @@ "political_content": "Politisch", "political_content.explanation": "Enthält politische Meinungen.", "sexual_content": "Sexueller Inhalt", - "sexual_content.explanation": "Contains sexual content.", + "sexual_content.explanation": "Enthält sexuelle Inhalte.", "spam.question": "Ist die Nachricht Spam?" } diff --git a/website/public/locales/de/message.json b/website/public/locales/de/message.json index 6a74a1c3..4eb709d3 100644 --- a/website/public/locales/de/message.json +++ b/website/public/locales/de/message.json @@ -1,13 +1,13 @@ { - "copy_message_id": "Copy message ID", + "copy_message_id": "Message ID kopieren", "label_action": "Label", "label_title": "Label", "message": "Nachricht", - "message_deleted": "Message deleted", + "message_deleted": "Nachricht gelöscht", "open_new_tab_action": "In neuem Tab öffnen", "parent": "Vorgänger", "reactions": "Reaktionen", - "recent_messages": "Recent Messages", + "recent_messages": "Kürzliche Nachrichten", "report_action": "Melden", "report_placeholder": "Warum sollte diese Nachricht überprüft werden?", "report_title": "Meldung", @@ -15,6 +15,6 @@ "stop_tree": "Stop tree", "submit_labels": "Absenden", "tree_stopped": "Tree stopped {{id}}", - "view_user": "View user", - "your_recent_messages": "Your Recent Messages" + "view_user": "User anzeigen", + "your_recent_messages": "Ihre kürzliche Nachrichten" } diff --git a/website/public/locales/de/tasks.json b/website/public/locales/de/tasks.json index a3e25217..c5646666 100644 --- a/website/public/locales/de/tasks.json +++ b/website/public/locales/de/tasks.json @@ -1,5 +1,5 @@ { - "available_task_count": "{{count}} tasks available", + "available_task_count": "{{count}} Aufgaben verfügbar", "classify_assistant_reply": { "label": "Antwort des Assistenten klassifizieren", "desc": "Labeln Sie die Antwort.", diff --git a/website/public/locales/de/tos.json b/website/public/locales/de/tos.json index 4d3d62b4..d424f5b5 100644 --- a/website/public/locales/de/tos.json +++ b/website/public/locales/de/tos.json @@ -1,6 +1,6 @@ { - "accept": "Accept", - "content": "To continue using Open Assistant, you have to accept our Terms of Service first.", - "decline": "Decline", - "title": "Terms of Service for Open Assistant" + "accept": "Akzeptieren", + "content": "Um Open Assistant weiterhin nutzen zu können, müssen Sie zunächst unsere Nutzungsbedingungen akzeptieren.", + "decline": "Ablehnen", + "title": "Nutzungsbedingungen für Open Assistant" } From a85cc0a47d44ac7fdcc82454de41bc6d3a2117d5 Mon Sep 17 00:00:00 2001 From: Yannic Kilcher Date: Thu, 9 Feb 2023 08:49:01 +0100 Subject: [PATCH 06/54] endpoint to list chats --- inference/server/main.py | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/inference/server/main.py b/inference/server/main.py index 0c282394..1f9f16af 100644 --- a/inference/server/main.py +++ b/inference/server/main.py @@ -39,14 +39,6 @@ redisClient = redis.Redis( ) -class CreateChatRequest(pydantic.BaseModel): - pass - - -class CreateChatResponse(pydantic.BaseModel): - id: str - - class MessageRequest(pydantic.BaseModel): message: str = pydantic.Field(..., repr=False) model_name: str = "distilgpt2" @@ -67,24 +59,47 @@ class MessageRequestState(str, enum.Enum): aborted_by_worker = "aborted_by_worker" +class CreateChatRequest(pydantic.BaseModel): + pass + + +class ChatListEntry(pydantic.BaseModel): + id: str + + +class ListChatsResponse(pydantic.BaseModel): + chats: list[ChatListEntry] + + class DbChatEntry(pydantic.BaseModel): id: str = pydantic.Field(default_factory=lambda: str(uuid.uuid4())) conversation: protocol.Conversation = pydantic.Field(default_factory=protocol.Conversation) pending_message_request: MessageRequest | None = None message_request_state: MessageRequestState | None = None + def to_list_entry(self) -> ChatListEntry: + return ChatListEntry(id=self.id) + # TODO: make real database CHATS: dict[str, DbChatEntry] = {} +@app.get("/chat") +async def list_chats() -> ListChatsResponse: + """Lists all chats.""" + logger.info("Listing all chats.") + chats = [chat.to_list_entry() for chat in CHATS.values()] + return ListChatsResponse(chats=chats) + + @app.post("/chat") -async def create_chat(request: CreateChatRequest) -> CreateChatResponse: +async def create_chat(request: CreateChatRequest) -> ChatListEntry: """Allows a client to create a new chat.""" logger.info(f"Received {request}") chat = DbChatEntry() CHATS[chat.id] = chat - return CreateChatResponse(id=chat.id) + return ChatListEntry(id=chat.id) @app.get("/chat/{id}") From c53d8e9bce3f9dbce4c574dcb3f5bb8cf5fc3bd6 Mon Sep 17 00:00:00 2001 From: Yannic Kilcher Date: Thu, 9 Feb 2023 08:52:45 +0100 Subject: [PATCH 07/54] changed return type of GET chat --- inference/server/main.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/inference/server/main.py b/inference/server/main.py index 1f9f16af..28e8df22 100644 --- a/inference/server/main.py +++ b/inference/server/main.py @@ -67,6 +67,11 @@ class ChatListEntry(pydantic.BaseModel): id: str +class ChatEntry(pydantic.BaseModel): + id: str + conversation: protocol.Conversation + + class ListChatsResponse(pydantic.BaseModel): chats: list[ChatListEntry] @@ -80,6 +85,9 @@ class DbChatEntry(pydantic.BaseModel): def to_list_entry(self) -> ChatListEntry: return ChatListEntry(id=self.id) + def to_entry(self) -> ChatEntry: + return ChatEntry(id=self.id, conversation=self.conversation) + # TODO: make real database CHATS: dict[str, DbChatEntry] = {} @@ -103,9 +111,9 @@ async def create_chat(request: CreateChatRequest) -> ChatListEntry: @app.get("/chat/{id}") -async def get_chat(id: str) -> protocol.Conversation: +async def get_chat(id: str) -> ChatEntry: """Allows a client to get the current state of a chat.""" - return CHATS[id].conversation + return CHATS[id].to_entry() @app.post("/chat/{id}/message") From 7c4ff7324122009070ab3320ccf81bc354e62029 Mon Sep 17 00:00:00 2001 From: Yannic Kilcher Date: Thu, 9 Feb 2023 09:20:00 +0100 Subject: [PATCH 08/54] corrected random seed for torch --- oasst-shared/oasst_shared/schemas/inference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oasst-shared/oasst_shared/schemas/inference.py b/oasst-shared/oasst_shared/schemas/inference.py index a638e55c..96b05c7b 100644 --- a/oasst-shared/oasst_shared/schemas/inference.py +++ b/oasst-shared/oasst_shared/schemas/inference.py @@ -13,7 +13,7 @@ class WorkRequest(pydantic.BaseModel): conversation: protocol.Conversation = pydantic.Field(..., repr=False) model_name: str = "distilgpt2" max_new_tokens: int = 100 - seed: int = pydantic.Field(default_factory=lambda: random.randint(0, 2**31 - 1)) + seed: int = pydantic.Field(default_factory=lambda: random.randint(0, 0xFFFF_FFFF_FFFF_FFFF - 1)) do_sample: bool = True top_k: int = 50 top_p: float = 0.9 From ef548edb728c941b92f66432c0c0b8a1a44cd6c4 Mon Sep 17 00:00:00 2001 From: notmd <33456881+notmd@users.noreply.github.com> Date: Thu, 9 Feb 2023 15:20:27 +0700 Subject: [PATCH 09/54] Trollboard expandable (#1354) * wip * hide necessary column in trollboard * remove console.log * fix build * clean up * remove commented code --- .../components/{ => DataTable}/DataTable.tsx | 26 +++++- .../DataTable/jsonExpandRowModel.tsx | 60 +++++++++++++ .../LeaderboardTable/LeaderboardTable.tsx | 33 ++++--- .../LeaderboardTable/TrollboardTable.tsx | 88 ++++++++++--------- .../LeaderboardTable/useBoardRowProps.ts | 2 +- website/src/components/UserTable.tsx | 2 +- website/src/pages/admin/trollboard.tsx | 2 +- 7 files changed, 153 insertions(+), 60 deletions(-) rename website/src/components/{ => DataTable}/DataTable.tsx (90%) create mode 100644 website/src/components/DataTable/jsonExpandRowModel.tsx diff --git a/website/src/components/DataTable.tsx b/website/src/components/DataTable/DataTable.tsx similarity index 90% rename from website/src/components/DataTable.tsx rename to website/src/components/DataTable/DataTable.tsx index 35246bf7..3e75f32e 100644 --- a/website/src/components/DataTable.tsx +++ b/website/src/components/DataTable/DataTable.tsx @@ -23,13 +23,23 @@ import { Tr, useDisclosure, } from "@chakra-ui/react"; -import { Cell, ColumnDef, flexRender, getCoreRowModel, Row, useReactTable } from "@tanstack/react-table"; +import { + Cell, + ColumnDef, + ExpandedState, + flexRender, + getCoreRowModel, + getExpandedRowModel, + Row, + useReactTable, +} from "@tanstack/react-table"; import { Filter } from "lucide-react"; import { useTranslation } from "next-i18next"; -import { ChangeEvent, ReactNode } from "react"; +import { ChangeEvent, ReactNode, useState } from "react"; import { useDebouncedCallback } from "use-debounce"; -export type DataTableColumnDef = ColumnDef & { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type DataTableColumnDef = ColumnDef & { filterable?: boolean; span?: number | ((cell: Cell) => number | undefined); }; @@ -54,6 +64,7 @@ export type DataTableProps = { disablePrevious?: boolean; disablePagination?: boolean; rowProps?: TableRowProps | DataTableRowPropsCallback; + getSubRows?: (row: T) => T[] | undefined; }; export const DataTable = ({ @@ -68,12 +79,21 @@ export const DataTable = ({ disablePrevious, disablePagination, rowProps, + getSubRows, }: DataTableProps) => { const { t } = useTranslation("leaderboard"); + const [expanded, setExpanded] = useState({}); + const { getHeaderGroups, getRowModel } = useReactTable({ data, columns, getCoreRowModel: getCoreRowModel(), + getExpandedRowModel: getExpandedRowModel(), + state: { + expanded, + }, + getSubRows, + onExpandedChange: setExpanded, }); const handleFilterChange = (value: FilterItem) => { diff --git a/website/src/components/DataTable/jsonExpandRowModel.tsx b/website/src/components/DataTable/jsonExpandRowModel.tsx new file mode 100644 index 00000000..84c70e20 --- /dev/null +++ b/website/src/components/DataTable/jsonExpandRowModel.tsx @@ -0,0 +1,60 @@ +import { Card, CardBody, Flex } from "@chakra-ui/react"; +import { Cell, CellContext } from "@tanstack/react-table"; +import { ChevronDown, ChevronRight } from "lucide-react"; + +type ExpandableRow = Omit & { + shouldExpand?: boolean; +}; + +export const createJsonExpandRowModel = () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const renderCell = ({ row, getValue }: CellContext, any>) => { + if (!row.original.shouldExpand) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { shouldExpand, ...res } = row.original; + return ( + + +
{JSON.stringify(res, null, 2)}
+
+
+ ); + } + + return ( + + {row.getCanExpand() ? ( + + ) : null}{" "} + {getValue()} + + ); + }; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const span = (cell: Cell, any>) => + cell.row.original.shouldExpand ? undefined : cell.row.getVisibleCells().length; + + const getSubRows = (row: ExpandableRow) => + row.shouldExpand + ? [ + { + ...row, + shouldExpand: false, + }, + ] + : undefined; + + const toExpandable = function (arr: T[] | undefined, val = true): ExpandableRow[] { + return !arr ? [] : arr.map((element) => ({ ...element, shouldExpand: val })); + }; + + return { renderCell, span, getSubRows, toExpandable }; +}; diff --git a/website/src/components/LeaderboardTable/LeaderboardTable.tsx b/website/src/components/LeaderboardTable/LeaderboardTable.tsx index d59fc902..fc3ae099 100644 --- a/website/src/components/LeaderboardTable/LeaderboardTable.tsx +++ b/website/src/components/LeaderboardTable/LeaderboardTable.tsx @@ -2,19 +2,20 @@ import { Box, CircularProgress, Flex, Link, useColorModeValue } from "@chakra-ui import { createColumnHelper } from "@tanstack/react-table"; import { MoreHorizontal } from "lucide-react"; import NextLink from "next/link"; -import { useSession } from "next-auth/react"; import { useTranslation } from "next-i18next"; import React, { useMemo } from "react"; +import { useHasRole } from "src/hooks/auth/useHasRole"; import { LeaderboardEntity, LeaderboardReply, LeaderboardTimeFrame } from "src/types/Leaderboard"; -import { DataTable, DataTableColumnDef } from "../DataTable"; +import { DataTable, DataTableColumnDef } from "../DataTable/DataTable"; +import { createJsonExpandRowModel } from "../DataTable/jsonExpandRowModel"; import { useBoardPagination } from "./useBoardPagination"; import { useBoardRowProps } from "./useBoardRowProps"; import { useFetchBoard } from "./useFetchBoard"; type WindowLeaderboardEntity = LeaderboardEntity & { isSpaceRow?: boolean }; const columnHelper = createColumnHelper(); - +const jsonExpandRowModel = createJsonExpandRowModel(); /** * Presents a grid of leaderboard entries with more detailed information. */ @@ -39,17 +40,24 @@ export const LeaderboardTable = ({ } = useFetchBoard( `/api/leaderboard?time_frame=${timeFrame}&limit=${limit}&includeUserStats=${!hideCurrentUserRanking}` ); - const { data: session } = useSession(); - const isAdmin = session?.user?.role === "admin"; + const isAdmin = useHasRole("admin"); + const columns: DataTableColumnDef[] = useMemo( () => [ { ...columnHelper.accessor("rank", { header: t("rank"), - cell: ({ row, getValue }) => (row.original.isSpaceRow ? : getValue()), + cell: (ctx) => + ctx.row.original.isSpaceRow ? ( + + ) : isAdmin ? ( + jsonExpandRowModel.renderCell(ctx) + ) : ( + ctx.getValue() + ), }), - span: (cell) => (cell.row.original.isSpaceRow ? 6 : undefined), + span: (cell) => (cell.row.original.isSpaceRow ? 6 : jsonExpandRowModel.span(cell)), }, columnHelper.accessor("display_name", { header: t("user"), @@ -82,17 +90,17 @@ export const LeaderboardTable = ({ data: paginatedData, end, ...pagnationProps - } = useBoardPagination({ rowPerPage, data: reply?.leaderboard, limit }); - const data: WindowLeaderboardEntity[] = useMemo(() => { - if (hideCurrentUserRanking || !reply?.user_stats_window) { + } = useBoardPagination({ rowPerPage, data: jsonExpandRowModel.toExpandable(reply?.leaderboard || []), limit }); + const data = useMemo(() => { + if (hideCurrentUserRanking || !reply?.user_stats_window || reply.user_stats_window.length === 0) { return paginatedData; } - const userStatsWindow: WindowLeaderboardEntity[] = reply.user_stats_window; + const userStatsWindow: WindowLeaderboardEntity[] = jsonExpandRowModel.toExpandable(reply.user_stats_window); const userStats = userStatsWindow.find((stats) => stats.highlighted); if (userStats && userStats.rank > end) { paginatedData.push( { isSpaceRow: true } as WindowLeaderboardEntity, - ...reply.user_stats_window.filter( + ...userStatsWindow.filter( (stats) => paginatedData.findIndex((leaderBoardEntity) => leaderBoardEntity.user_id === stats.user_id) === -1 ) // filter to avoid duplicated row ); @@ -116,6 +124,7 @@ export const LeaderboardTable = ({ columns={columns} caption={lastUpdated} rowProps={rowProps} + getSubRows={jsonExpandRowModel.getSubRows} {...pagnationProps} > ); diff --git a/website/src/components/LeaderboardTable/TrollboardTable.tsx b/website/src/components/LeaderboardTable/TrollboardTable.tsx index 1b1ea118..0c971655 100644 --- a/website/src/components/LeaderboardTable/TrollboardTable.tsx +++ b/website/src/components/LeaderboardTable/TrollboardTable.tsx @@ -1,26 +1,42 @@ -import { Box, CircularProgress, Flex, Link } from "@chakra-ui/react"; +import { Box, CircularProgress, Flex, IconButton, Link, Tooltip } from "@chakra-ui/react"; import { createColumnHelper } from "@tanstack/react-table"; -import { ThumbsDown, ThumbsUp } from "lucide-react"; +import { Mail, ThumbsDown, ThumbsUp, User } from "lucide-react"; import NextLink from "next/link"; import { FetchTrollBoardResponse, TrollboardEntity, TrollboardTimeFrame } from "src/types/Trollboard"; -import { DataTable } from "../DataTable"; +import { DataTable, DataTableColumnDef } from "../DataTable/DataTable"; +import { createJsonExpandRowModel } from "../DataTable/jsonExpandRowModel"; +import { Discord } from "../Icons/Discord"; import { useBoardPagination } from "./useBoardPagination"; import { useBoardRowProps } from "./useBoardRowProps"; import { useFetchBoard } from "./useFetchBoard"; + const columnHelper = createColumnHelper(); - const toPercentage = (num: number) => `${Math.round(num * 100)}%`; +const jsonExpandRowModel = createJsonExpandRowModel(); -const columns = [ - columnHelper.accessor("rank", {}), +const columns: DataTableColumnDef[] = [ + { + ...columnHelper.accessor("rank", { + cell: jsonExpandRowModel.renderCell, + }), + span: jsonExpandRowModel.span, + }, columnHelper.accessor("display_name", { header: "Display name", - cell: ({ getValue, row }) => ( - - {getValue()} - - ), + cell: ({ getValue, row }) => { + const isEmail = row.original.auth_method === "local"; + return ( + + + {getValue()} + + + {isEmail ? : } + + + ); + }, }), columnHelper.accessor("troll_score", { header: "Troll score", @@ -45,36 +61,19 @@ const columns = [ columnHelper.accessor((row) => row.spam + row.spam_prompts, { header: "Spam", }), - columnHelper.accessor("lang_mismach", { - header: "Lang mismach", - }), - columnHelper.accessor("not_appropriate", { - header: "Not appropriate", - }), - columnHelper.accessor("pii", {}), - columnHelper.accessor("hate_speech", { - header: "Hate speech", - }), - columnHelper.accessor("sexual_content", { - header: "Sexual Content", - }), - columnHelper.accessor("political_content", { - header: "Political Content", - }), - columnHelper.accessor("quality", { - cell: ({ getValue }) => toPercentage(getValue()), - }), - columnHelper.accessor("helpfulness", { - cell: ({ getValue }) => toPercentage(getValue()), - }), - columnHelper.accessor("humor", { - cell: ({ getValue }) => toPercentage(getValue()), - }), - columnHelper.accessor("violence", { - cell: ({ getValue }) => toPercentage(getValue()), - }), columnHelper.accessor("toxicity", { - cell: ({ getValue }) => toPercentage(getValue()), + cell: ({ getValue }) => toPercentage(getValue() || 0), + }), + columnHelper.accessor((row) => row.user_id, { + header: "Actions", + cell: ({ row }) => ( + } + > + ), }), ]; @@ -94,7 +93,11 @@ export const TrollboardTable = ({ lastUpdated, } = useFetchBoard(`/api/admin/trollboard?time_frame=${timeFrame}&limit=${limit}`); - const { data, ...paginationProps } = useBoardPagination({ rowPerPage, data: trollboardRes?.trollboard, limit }); + const { data, ...paginationProps } = useBoardPagination({ + rowPerPage, + data: jsonExpandRowModel.toExpandable(trollboardRes?.trollboard), + limit, + }); const rowProps = useBoardRowProps(); if (isLoading) { return ; @@ -112,11 +115,12 @@ export const TrollboardTable = ({ }, }} > - + diff --git a/website/src/components/LeaderboardTable/useBoardRowProps.ts b/website/src/components/LeaderboardTable/useBoardRowProps.ts index 32f3fc56..be0fe7de 100644 --- a/website/src/components/LeaderboardTable/useBoardRowProps.ts +++ b/website/src/components/LeaderboardTable/useBoardRowProps.ts @@ -2,7 +2,7 @@ import { useColorModeValue, useToken } from "@chakra-ui/react"; import { useCallback } from "react"; import { colors } from "src/styles/Theme/colors"; -import { DataTableRowPropsCallback } from "../DataTable"; +import { DataTableRowPropsCallback } from "../DataTable/DataTable"; export const useBoardRowProps = () => { const borderColor = useToken("colors", useColorModeValue(colors.light.active, colors.dark.active)); diff --git a/website/src/components/UserTable.tsx b/website/src/components/UserTable.tsx index ab05d065..5c51c585 100644 --- a/website/src/components/UserTable.tsx +++ b/website/src/components/UserTable.tsx @@ -7,7 +7,7 @@ import { get } from "src/lib/api"; import type { FetchUsersResponse, User } from "src/types/Users"; import useSWR from "swr"; -import { DataTable, DataTableColumnDef, FilterItem } from "./DataTable"; +import { DataTable, DataTableColumnDef, FilterItem } from "./DataTable/DataTable"; interface Pagination { /** diff --git a/website/src/pages/admin/trollboard.tsx b/website/src/pages/admin/trollboard.tsx index aaef80f3..47e69d6b 100644 --- a/website/src/pages/admin/trollboard.tsx +++ b/website/src/pages/admin/trollboard.tsx @@ -18,7 +18,7 @@ const Leaderboard = () => { - {t("leaderboard")} + Trollboard From 7b16ee9a7568e5ae92f8edf4fd4f8e74fda8d0c3 Mon Sep 17 00:00:00 2001 From: Keith Stevens Date: Thu, 9 Feb 2023 19:29:11 +0900 Subject: [PATCH 10/54] When loading recent messages, filter by the user's stored language. (#1292) A simple short term fix. Applies to #962. To fully fix a small backend change is needed. --- website/public/locales/en/message.json | 2 +- website/src/lib/oasst_api_client.ts | 4 ++-- website/src/pages/api/messages/index.ts | 4 +++- website/src/pages/messages/index.tsx | 7 ++++++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/website/public/locales/en/message.json b/website/public/locales/en/message.json index a531f0a4..75565656 100644 --- a/website/public/locales/en/message.json +++ b/website/public/locales/en/message.json @@ -8,7 +8,7 @@ "open_new_tab_action": "Open in new tab", "parent": "Parent", "reactions": "Reactions", - "recent_messages": "Recent Messages", + "recent_messages": "Recent Messages in {{language}}", "report_action": "Report", "report_placeholder": "Why should this message be reviewed?", "report_title": "Report", diff --git a/website/src/lib/oasst_api_client.ts b/website/src/lib/oasst_api_client.ts index 826fc195..2ec76c85 100644 --- a/website/src/lib/oasst_api_client.ts +++ b/website/src/lib/oasst_api_client.ts @@ -314,8 +314,8 @@ export class OasstApiClient { return this.get(`/api/v1/messages?${params}`); } - fetch_recent_messages() { - return this.get(`/api/v1/messages`); + fetch_recent_messages(lang: string) { + return this.get(`/api/v1/messages`, { lang }); } fetch_message_children(messageId: string) { diff --git a/website/src/pages/api/messages/index.ts b/website/src/pages/api/messages/index.ts index fbcaee3c..978ed3ff 100644 --- a/website/src/pages/api/messages/index.ts +++ b/website/src/pages/api/messages/index.ts @@ -1,9 +1,11 @@ import { withoutRole } from "src/lib/auth"; import { createApiClient } from "src/lib/oasst_client_factory"; +import { getUserLanguage } from "src/lib/users"; const handler = withoutRole("banned", async (req, res, token) => { const client = await createApiClient(token); - const messages = await client.fetch_recent_messages(); + const userLanguage = getUserLanguage(req); + const messages = await client.fetch_recent_messages(userLanguage); res.status(200).json(messages); }); diff --git a/website/src/pages/messages/index.tsx b/website/src/pages/messages/index.tsx index 8d950a2b..4cae792a 100644 --- a/website/src/pages/messages/index.tsx +++ b/website/src/pages/messages/index.tsx @@ -1,6 +1,7 @@ import { Box, CircularProgress, SimpleGrid, Text, useColorModeValue } from "@chakra-ui/react"; import Head from "next/head"; import { useTranslation } from "next-i18next"; +import { useCookies } from "react-cookie"; import { getDashboardLayout } from "src/components/Layout"; import { MessageTable } from "src/components/Messages/MessageTable"; import { get } from "src/lib/api"; @@ -15,6 +16,8 @@ const MessagesDashboard = () => { const { data: messages } = useSWRImmutable("/api/messages", get, { revalidateOnMount: true }); const { data: userMessages } = useSWRImmutable(`/api/messages/user`, get, { revalidateOnMount: true }); + const [cookies] = useCookies(["NEXT_LOCALE"]); + const currentLanguage = cookies["NEXT_LOCALE"] || "en"; return ( <> @@ -24,7 +27,9 @@ const MessagesDashboard = () => { - {t("recent_messages")} + {t("recent_messages", { + language: new Intl.DisplayNames([currentLanguage], { type: "language" }).of(currentLanguage), + })} Date: Thu, 9 Feb 2023 17:31:04 +0700 Subject: [PATCH 11/54] fix message reaction count visibility (#1382) close #1367 * Only show when the user is author, admin or has reacted to the message for all pages. * Add disabled state when user is author --- .../Messages/MessageEmojiButton.stories.tsx | 15 ++++----- .../Messages/MessageEmojiButton.tsx | 31 ++++++++++++++++--- .../components/Messages/MessageTableEntry.tsx | 3 +- website/src/types/Conversation.ts | 8 +++++ 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/website/src/components/Messages/MessageEmojiButton.stories.tsx b/website/src/components/Messages/MessageEmojiButton.stories.tsx index b083c966..5d3e8be6 100644 --- a/website/src/components/Messages/MessageEmojiButton.stories.tsx +++ b/website/src/components/Messages/MessageEmojiButton.stories.tsx @@ -11,17 +11,16 @@ export default { const Template = ({ emoji, count, - checked, - showCount, + ...rest }: { emoji: string; count: number; checked?: boolean; - showCount: boolean; + userIsAuthor: boolean; + disabled?: boolean; + userReacted: boolean; }) => { - return ( - - ); + return ; }; export const Default = Template.bind({}); @@ -29,7 +28,9 @@ Default.args = { emoji: "+1", count: 7, checked: false, - showCount: true, + userIsAuthor: false, + disabled: false, + userReacted: true, }; export const BigNumber = Template.bind({}); diff --git a/website/src/components/Messages/MessageEmojiButton.tsx b/website/src/components/Messages/MessageEmojiButton.tsx index f140a789..e3acb3c0 100644 --- a/website/src/components/Messages/MessageEmojiButton.tsx +++ b/website/src/components/Messages/MessageEmojiButton.tsx @@ -1,4 +1,5 @@ import { Button } from "@chakra-ui/react"; +import { useHasRole } from "src/hooks/auth/useHasRole"; import { MessageEmoji } from "src/types/Conversation"; import { emojiIcons } from "src/types/Emoji"; @@ -6,12 +7,27 @@ interface MessageEmojiButtonProps { emoji: MessageEmoji; checked?: boolean; onClick: () => void; - showCount: boolean; + userIsAuthor: boolean; + disabled?: boolean; + userReacted: boolean; } -export const MessageEmojiButton = ({ emoji, checked, onClick, showCount }: MessageEmojiButtonProps) => { +export const MessageEmojiButton = ({ + emoji, + checked, + onClick, + userIsAuthor, + disabled, + userReacted, +}: MessageEmojiButtonProps) => { const EmojiIcon = emojiIcons.get(emoji.name); - if (!EmojiIcon) return <>; + const isAdmin = useHasRole("admin"); + + if (!EmojiIcon) return null; + + const isDisabled = !!(userIsAuthor ? true : disabled); + const showCount = (emoji.count > 0 && userReacted) || userIsAuthor || isAdmin; + return ( ); }; diff --git a/website/src/components/Messages/MessageTableEntry.tsx b/website/src/components/Messages/MessageTableEntry.tsx index a82cc50c..c469de70 100644 --- a/website/src/components/Messages/MessageTableEntry.tsx +++ b/website/src/components/Messages/MessageTableEntry.tsx @@ -116,7 +116,8 @@ export function MessageTableEntry({ message, enabled, highlight }: MessageTableE key={emoji} emoji={{ name: emoji, count }} checked={emojiState.user_emojis.includes(emoji)} - showCount={emojiState.user_emojis.filter((emoji) => emoji === "+1" || emoji === "-1").length > 0} + userReacted={emojiState.user_emojis.length > 0} + userIsAuthor={message.user_is_author} onClick={() => react(emoji, !emojiState.user_emojis.includes(emoji))} /> ); diff --git a/website/src/types/Conversation.ts b/website/src/types/Conversation.ts index 5eb86351..89713107 100644 --- a/website/src/types/Conversation.ts +++ b/website/src/types/Conversation.ts @@ -19,6 +19,14 @@ export interface Message extends MessageEmojis { parent_id: string; frontend_message_id?: string; user_id: string; + user_is_author: boolean | null; + deleted: boolean | null; + synthetic: boolean | null; + message_tree_id: string; + ranking_count: number | null; + rank: number | null; + model_name: string | null; + review_count: number | null; } export interface Conversation { From 0187d4c17af771f9d5900480a9a2ff5878072171 Mon Sep 17 00:00:00 2001 From: Mehdi Zibout <113536090+mehdi-zibout@users.noreply.github.com> Date: Thu, 9 Feb 2023 11:31:43 +0100 Subject: [PATCH 12/54] Fix avatar not displaying correctly in the navbar (#1383) --- website/src/components/Header/UserMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/components/Header/UserMenu.tsx b/website/src/components/Header/UserMenu.tsx index 8b5de035..cad2dbe8 100644 --- a/website/src/components/Header/UserMenu.tsx +++ b/website/src/components/Header/UserMenu.tsx @@ -69,7 +69,7 @@ export function UserMenu() { - + {session.user.name || "New User"} From e8f1bd0737e30ca30a69e9b2136394287e1c95ef Mon Sep 17 00:00:00 2001 From: lytjedk <124836469+lytjedk@users.noreply.github.com> Date: Thu, 9 Feb 2023 10:54:26 +0000 Subject: [PATCH 13/54] Create dashboard.json (#1381) --- website/public/locales/da/dashboard.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 website/public/locales/da/dashboard.json diff --git a/website/public/locales/da/dashboard.json b/website/public/locales/da/dashboard.json new file mode 100644 index 00000000..79c790ef --- /dev/null +++ b/website/public/locales/da/dashboard.json @@ -0,0 +1,8 @@ +{ + "grab_a_task": "Tag en opgave!", + "create": "Lav", + "evaluate": "Evaluer", + "label": "Label", + "dashboard": "Dashboard", + "go": "Start" +} From f3debae3ca566c089a75c441cd2d336b16cf47be Mon Sep 17 00:00:00 2001 From: CactiStaccingCrane <121211419+CactiStaccingCrane@users.noreply.github.com> Date: Thu, 9 Feb 2023 18:44:31 +0700 Subject: [PATCH 14/54] Fix Vietnamese translation (#1384) --- website/public/locales/vi/common.json | 13 +++-------- website/public/locales/vi/index.json | 8 +++---- website/public/locales/vi/leaderboard.json | 6 ++--- website/public/locales/vi/message.json | 10 ++++----- website/public/locales/vi/side_menu.json | 12 ++++++++++ website/public/locales/vi/tasks.json | 26 +++++++++++----------- 6 files changed, 40 insertions(+), 35 deletions(-) create mode 100644 website/public/locales/vi/side_menu.json diff --git a/website/public/locales/vi/common.json b/website/public/locales/vi/common.json index 71309549..aa2cc855 100644 --- a/website/public/locales/vi/common.json +++ b/website/public/locales/vi/common.json @@ -3,21 +3,17 @@ "account_settings": "Tài khoản", "admin_dashboard": "Trang cho admin", "connect": "Liên hệ", - "conversational": "Chatbot AI cho tất cả mọi người", - "copied": "Copied", + "conversational": "Chatbot AI cho mọi người", + "copied": "Đã sao chép", "dark_mode": "Giao diện tối", - "dashboard_home": "Trang chính", "dashboard": "Trang chính", "delete": "Xoá", "discord": "Discord", "docs": "Hướng dẫn", "github": "GitHub", - "leaderboard": "Bảng xếp hạng", "legal": "Luật lệ", "light_mode": "Giao diện sáng", "loading": "Đang tải...", - "messages_dashboard": "Bảng xếp hạng tin nhắn", - "messages": "Tin nhắn", "more_information": "Xem thêm", "no": "Không", "privacy_policy": "Chính sách bảo mật", @@ -26,11 +22,8 @@ "sign_out": "Đăng xuất", "status_dashboard": "Trang hiện tình trạng", "status": "Tình trạng", - "success": "Success", + "success": "Thành công", "terms_of_service": "Điều khoản sử dụng", "title": "Open Assistant", - "user_leaderboard": "Bảng xếp hạng người dùng", - "users_dashboard": "Trang về người dùng", - "users": "Người dùng", "yes": "Có" } diff --git a/website/public/locales/vi/index.json b/website/public/locales/vi/index.json index 43022145..1c6b5e19 100644 --- a/website/public/locales/vi/index.json +++ b/website/public/locales/vi/index.json @@ -1,15 +1,15 @@ { "blurb": "Đây sẽ là cuộc cách mạng công nghệ mới.", - "blurb1": "Giống như cách Stable Diffusion đã cho mọi người công cụ để làm tranh ảnh bằng AI, Open Assistant sẽ làm như vậy với con chatbot mã nguồn mở mạnh nhất thế giới.", - "description": "Chatbot trí tuệ nhân tạo mã nguồn mở, dựa trên mô hình ngôn ngữ lớn của LAION và các tình nguyện viên trên toàn thế giới.", + "blurb1": "Giống như Stable Diffusion với tranh ảnh bằng AI, Open Assistant sẽ làm tương tự như vậy với con chatbot mã nguồn mở mạnh nhất thế giới.", + "description": "Chatbot trí tuệ nhân tạo mã nguồn mở, dựa trên mô hình ngôn ngữ lớn của LAION và các tình nguyện.", "faq_items": { "q0": "Open Assistant bây giờ thế nào rồi?", "a0": "Dự án này đang trong giai đoạn phát triển, từ những nghiên cứu về sử dụng RLHF (học từ phản hồi con người) trong các mô hình ngôn ngữ lớn.", "q1": "Open Assistant được phát triển bởi ai?", - "a1": "Open Assistant là dự ản được phát triển bởi LAION and các tình nguyện viên trên toàn thế giới." + "a1": "Open Assistant là dự ản được phát triển bởi LAION and các tình nguyện viên." }, "faq_title": "Câu hỏi", "join_us_description": "Các dự án mã nguồn mở được phát triển bởi những người như bạn. Triết lý mã nguồn mở là hợp tác để tạo và phát triển công nghệ mới mà làm giàu thế giới quanh ta. Bạn có muốn tham gia không? Liên hệ chúng tôi ở đây:", "join_us_title": "Tham gia", - "subtitle": "Chatbot AI cho tất cả mọi người" + "subtitle": "Chatbot AI cho mọi người" } diff --git a/website/public/locales/vi/leaderboard.json b/website/public/locales/vi/leaderboard.json index ebe25dda..d5b4e167 100644 --- a/website/public/locales/vi/leaderboard.json +++ b/website/public/locales/vi/leaderboard.json @@ -1,15 +1,15 @@ { "daily": "Ngày", - "label": "Nhãn", + "label": "Số nhãn", "last_updated_at": "Cập nhật lần cuối: {{val, datetime}}", "leaderboard": "Bảng xếp hạng", "monthly": "Tháng", "next": "Tiếp", "overall": "Tổng quan", "previous": "Trước", - "prompt": "Câu đầu tiên", + "prompt": "Số câu đầu", "rank": "Xếp hạng", - "reply": "Câu trả lời", + "reply": "Số câu trả lời", "score": "Điểm", "top_5_contributors_today": "Top 5 người đóng góp", "user": "Tên người dùng", diff --git a/website/public/locales/vi/message.json b/website/public/locales/vi/message.json index baabe4b6..45d53060 100644 --- a/website/public/locales/vi/message.json +++ b/website/public/locales/vi/message.json @@ -1,20 +1,20 @@ { - "copy_message_id": "Copy message ID", + "copy_message_id": "Sao chép ID", "label_action": "Nhãn", "label_title": "Nhãn", "message": "Tin nhắn", - "message_deleted": "Message deleted", + "message_deleted": "Tin nhắn đã xoá", "open_new_tab_action": "Mở ở trang mới", "parent": "Tin nhắn gốc", "reactions": "Bình luận", "recent_messages": "Tin nhắn gần đây", "report_action": "Báo cáo", - "report_placeholder": "Tại sao tin nhắn này cần được báo cáo?", + "report_placeholder": "Nêu lý do để báo cáo", "report_title": "Báo cáo", "send_report": "Gửi", - "stop_tree": "Stop tree", + "stop_tree": "Dừng nhánh tin nhắn", "submit_labels": "Gửi", - "tree_stopped": "Tree stopped {{id}}", + "tree_stopped": "Nhánh tin nhắn {{id}} đã dừng", "view_user": "Xem người dùng", "your_recent_messages": "Tin nhắn gần đây của bạn" } diff --git a/website/public/locales/vi/side_menu.json b/website/public/locales/vi/side_menu.json new file mode 100644 index 00000000..6b06846f --- /dev/null +++ b/website/public/locales/vi/side_menu.json @@ -0,0 +1,12 @@ +{ + "dashboard": "Trang chính", + "dashboard_home": "Trang chính", + "leaderboard": "Bảng xếp hạng", + "messages": "Tin nhắn", + "messages_dashboard": "Bảng xếp hạng tin nhắn", + "status": "Tình trạng", + "status_dashboard": "Trang hiện tình trạng", + "user_leaderboard": "Bảng xếp hạng người dùng", + "users": "Người dùng", + "users_dashboard": "Trang về người dùng" +} diff --git a/website/public/locales/vi/tasks.json b/website/public/locales/vi/tasks.json index e197c410..7884f5fe 100644 --- a/website/public/locales/vi/tasks.json +++ b/website/public/locales/vi/tasks.json @@ -1,22 +1,22 @@ { "available_task_count": "{{count}} việc", "classify_assistant_reply": { - "label": "Phân loại tin nhắn của Open Assistant", - "desc": "Tạo nhãn dữ liệu đánh giá tin nhắn.", + "label": "Phân loại các tin nhắn của Open Assistant", + "desc": "Tạo nhãn dữ liệu để đánh giá tin nhắn.", "overview": "Từ cuộc trò truyện ở dưới, trả lời các câu hỏi về câu trả lời cuối trong cuộc trò truyện." }, "classify_initial_prompt": { - "label": "Phân loại tin nhắn đầu", - "desc": "Tạo nhãn dữ liệu đánh giá tin nhắn.", + "label": "Phân loại các tin nhắn đầu tiên", + "desc": "Tạo nhãn dữ liệu để đánh giá tin nhắn.", "overview": "Đọc tin nhắn đầu và trả lời các câu hỏi." }, "classify_prompter_reply": { "label": "Phân loại tin nhắn người dùng", - "desc": "Tạo nhãn dữ liệu đánh giá tin nhắn.", + "desc": "Tạo nhãn dữ liệu để đánh giá tin nhắn.", "overview": "Từ cuộc trò truyện ở dưới, trả lời các câu hỏi về câu trả lời cuối trong cuộc trò truyện." }, "create_initial_prompt": { - "label": "Tạo tin nhắn đầu", + "label": "Tạo tin nhắn đầu tiên", "desc": "Viết tin nhắn đầu tiên để làm bộ dữ liệu cho Open Assistant.", "overview": "Viết tin nhắn đầu tiên để Open Assistant trả lời", "instruction": "Viết tin nhắn đầu", @@ -27,17 +27,17 @@ "unchanged_message": "Are you sure you would like to continue?" }, "label_assistant_reply": { - "label": "Tạo nhãn cho tin nhắn của Open Assistant", + "label": "Đánh giá các tin nhắn của Open Assistant", "desc": "Tạo nhãn dữ liệu đánh giá tin nhắn của Open Assistant.", "overview": "Từ cuộc trò truyện ở dưới, tạo nhãn dữ liệu cho tin nhắn sau." }, "label_initial_prompt": { - "label": "Tạo nhãn cho tin nhắn đầu", + "label": "Đánh giá các tin nhắn đầu tiên", "desc": "Tạo nhãn dữ liệu đánh giá tin nhắn đầu.", "overview": "Tạo nhãn dữ liệu cho tin nhắn sau." }, "label_prompter_reply": { - "label": "Tạo nhãn cho tin nhắn người dùng", + "label": "Đánh giá các tin nhắn người dùng", "desc": "Tạo nhãn dữ liệu đánh giá tin nhắn của người dùng.", "overview": "Từ cuộc trò truyện ở dưới, tạo nhãn dữ liệu cho tin nhắn sau." }, @@ -46,28 +46,28 @@ "desc": "Giúp cải thiện Open Assistant bằng cách làm một việc ngẫu nhiên." }, "rank_assistant_replies": { - "label": "Xếp hạng câu trả lời của Open Assistant", + "label": "Xếp hạng các câu trả lời của Open Assistant", "desc": "Đánh giá độ chính xác và dễ đọc của các câu trả lời mà Open Assistant đưa ra.", "overview": "Từ những câu trả lời của Open Assistant, xếp hạng chúng theo chất lượng, tốt nhât ở trên, tệ nhất ở dưới.", "unchanged_title": "Chưa thay đổi thứ tự", "unchanged_message": "Bạn chưa thay đổi thứ tự tin nhắn. Bạn có chắc muốn lưu không?" }, "rank_initial_prompts": { - "label": "Xếp hạng tin nhắn đầu tiên", + "label": "Xếp hạng các tin nhắn đầu tiên", "desc": "Đánh giá độ chính xác và dễ đọc của các câu trả lời của tin nhắn đầu tiên.", "overview": "Từ những tin nhắn đầu sau, xếp hạng chúng theo chất lượng, tốt nhât ở trên, tệ nhất ở dưới.", "unchanged_title": "Chưa thay đổi thứ tự", "unchanged_message": "Bạn chưa thay đổi thứ tự tin nhắn. Bạn có chắc muốn lưu không?" }, "rank_user_replies": { - "label": "Xếp hạng câu trả lời của người dùng", + "label": "Xếp hạng các câu trả lời của người dùng", "desc": "Giúp cải thiện câu trả lời của Open Assistant.", "overview": "Từ những câu trả lời của người dùng, xếp hạng chúng theo chất lượng, tốt nhât ở trên, tệ nhất ở dưới.", "unchanged_title": "Chưa thay đổi thứ tự", "unchanged_message": "Bạn chưa thay đổi thứ tự tin nhắn. Bạn có chắc muốn lưu không?" }, "reply_as_assistant": { - "label": "Đóng vai Open Assistant", + "label": "Đóng vai trợ lý", "desc": "Giúp cải thiện câu trả lời của Open Assistant.", "overview": "Tạo câu trả lời phù hợp cho cuộc trò truyện dưới đây", "response_placeholder": "Viết vào đây..." From 1fd713bba353e002d92ea5f84385eff528a24188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=B6pf?= Date: Thu, 9 Feb 2023 13:15:53 +0100 Subject: [PATCH 15/54] fix lang filtering --- backend/oasst_backend/prompt_repository.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/oasst_backend/prompt_repository.py b/backend/oasst_backend/prompt_repository.py index f2119e3b..eb244d3b 100644 --- a/backend/oasst_backend/prompt_repository.py +++ b/backend/oasst_backend/prompt_repository.py @@ -947,6 +947,9 @@ class PromptRepository: if deleted is not None: qry = qry.filter(Message.deleted == deleted) + if lang is not None: + qry = qry.filter(Message.lang == lang) + if desc: qry = qry.order_by(Message.created_date.desc(), Message.id.desc()) else: @@ -955,9 +958,6 @@ class PromptRepository: if limit is not None: qry = qry.limit(limit) - if lang is not None: - qry = qry.filter(Message.lang == lang) - return self._add_user_emojis_all(qry) def update_children_counts(self, message_tree_id: UUID): From ed7d920e5df180d8aa08227e4dc5e635d9b343dc Mon Sep 17 00:00:00 2001 From: Yannic Kilcher Date: Thu, 9 Feb 2023 15:31:46 +0100 Subject: [PATCH 16/54] robustifying inference --- inference/server/main.py | 9 ++++++- inference/text-client/__main__.py | 43 +++++++++++++++++-------------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/inference/server/main.py b/inference/server/main.py index 28e8df22..4b2474da 100644 --- a/inference/server/main.py +++ b/inference/server/main.py @@ -216,17 +216,24 @@ async def work(websocket: fastapi.WebSocket): break try: + in_progress = False while True: # maybe unnecessary to parse and re-serialize # could just pass the raw string and mark end via empty string response_packet = inference.WorkResponsePacket.parse_raw(await websocket.receive_text()) + in_progress = True await redisClient.rpush(chat.id, response_packet.json()) if response_packet.is_end: break except fastapi.WebSocketException: # TODO: handle this better logger.exception(f"Websocket closed during handling of {chat.id}") - chat.message_request_state = MessageRequestState.aborted_by_worker + if in_progress: + logger.warning(f"Aborting {chat.id=}") + chat.message_request_state = MessageRequestState.aborted_by_worker + else: + logger.warning(f"Marking {chat.id=} as pending since no work was done.") + chat.message_request_state = MessageRequestState.pending raise chat.message_request_state = MessageRequestState.complete diff --git a/inference/text-client/__main__.py b/inference/text-client/__main__.py index 4a7fa110..8484978e 100644 --- a/inference/text-client/__main__.py +++ b/inference/text-client/__main__.py @@ -12,28 +12,33 @@ app = typer.Typer() @app.command() def main(backend_url: str = "http://127.0.0.1:8000"): """Simple REPL client.""" - chat_id = requests.post(f"{backend_url}/chat", json={}).json()["id"] while True: - message = typer.prompt("User").strip() + try: + chat_id = requests.post(f"{backend_url}/chat", json={}).json()["id"] + typer.echo(f"Chat ID: {chat_id}") + while True: + message = typer.prompt("User").strip() - # wait for stream to be ready - # could implement a queue position indicator - # could be implemented with long polling - # but server load needs to be considered - response = requests.post( - f"{backend_url}/chat/{chat_id}/message", - json={"message": message}, - stream=True, - headers={"Accept": "text/event-stream"}, - ) - response.raise_for_status() + # wait for stream to be ready + # could implement a queue position indicator + # could be implemented with long polling + # but server load needs to be considered + response = requests.post( + f"{backend_url}/chat/{chat_id}/message", + json={"message": message}, + stream=True, + headers={"Accept": "text/event-stream"}, + ) + response.raise_for_status() - client = sseclient.SSEClient(response) - print("Assistant: ", end="", flush=True) - for event in client.events(): - data = json.loads(event.data) - print(data["token"]["text"], end="", flush=True) - print() + client = sseclient.SSEClient(response) + print("Assistant: ", end="", flush=True) + for event in client.events(): + data = json.loads(event.data) + print(data["token"]["text"], end="", flush=True) + print() + except Exception: + typer.echo("Error, restarting chat...") if __name__ == "__main__": From 4784cf02eb845933622fbf3ce7857bcdcf3f7848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=B6pf?= Date: Thu, 9 Feb 2023 15:34:46 +0100 Subject: [PATCH 17/54] add cp of export.py to backend dockerfile --- docker/Dockerfile.backend | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/Dockerfile.backend b/docker/Dockerfile.backend index 3401463c..df9f1858 100644 --- a/docker/Dockerfile.backend +++ b/docker/Dockerfile.backend @@ -14,5 +14,6 @@ COPY ./backend/alembic /app/alembic COPY ./backend/alembic.ini /app/alembic.ini COPY ./backend/main.py /app/main.py COPY ./backend/import.py /app/import.py +COPY ./backend/export.py /app/export.py COPY ./backend/oasst_backend /app/oasst_backend COPY ./backend/test_data /app/test_data From eb340e0d9abb6d002b50017b07338bc638e5e29e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=B6pf?= Date: Thu, 9 Feb 2023 14:52:02 +0000 Subject: [PATCH 18/54] removed a ':' for copy message link --- website/src/components/Messages/MessageTableEntry.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/components/Messages/MessageTableEntry.tsx b/website/src/components/Messages/MessageTableEntry.tsx index c469de70..6710f9ea 100644 --- a/website/src/components/Messages/MessageTableEntry.tsx +++ b/website/src/components/Messages/MessageTableEntry.tsx @@ -238,7 +238,7 @@ const MessageActions = ({ handleCopy(`${window.location.protocol}://${window.location.host}/messages/${id}`)} + onClick={() => handleCopy(`${window.location.protocol}//${window.location.host}/messages/${id}`)} icon={} > {t("copy_message_link")} From 898ce2021602af4aced1a492ecff255a6cf9010c Mon Sep 17 00:00:00 2001 From: CactiStaccingCrane <121211419+CactiStaccingCrane@users.noreply.github.com> Date: Thu, 9 Feb 2023 23:17:34 +0700 Subject: [PATCH 19/54] Update Vietnamese translation (#1389) * Update Vietnamese translation * Update common.json --- website/public/locales/vi/common.json | 12 ++++++++++-- website/public/locales/vi/index.json | 14 +++++++++++--- website/public/locales/vi/leaderboard.json | 21 ++++++++++++++++++--- website/public/locales/vi/tasks.json | 6 ++++-- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/website/public/locales/vi/common.json b/website/public/locales/vi/common.json index aa2cc855..f02091b6 100644 --- a/website/public/locales/vi/common.json +++ b/website/public/locales/vi/common.json @@ -6,24 +6,32 @@ "conversational": "Chatbot AI cho mọi người", "copied": "Đã sao chép", "dark_mode": "Giao diện tối", + "dashboard_home": "Trang chính", "dashboard": "Trang chính", "delete": "Xoá", "discord": "Discord", "docs": "Hướng dẫn", "github": "GitHub", + "leaderboard": "Bảng xếp hạng", "legal": "Luật lệ", "light_mode": "Giao diện sáng", "loading": "Đang tải...", + "messages_dashboard": "Trang tin nhắn", + "messages": "Tin nhắn", "more_information": "Xem thêm", "no": "Không", + "parameters": "Thông số", "privacy_policy": "Chính sách bảo mật", "report_a_bug": "Báo lỗi", "sign_in": "Đăng nhập", "sign_out": "Đăng xuất", - "status_dashboard": "Trang hiện tình trạng", "status": "Tình trạng", + "status_dashboard": "Trang tình trạng", "success": "Thành công", - "terms_of_service": "Điều khoản sử dụng", "title": "Open Assistant", + "trollboard": "Trang giám sát", + "user_leaderboard": "Bảng xếp hạng người dùng", + "users_dashboard": "Bảng xếp hạng người dùng", + "terms_of_service": "Điều khoản sử dụng", "yes": "Có" } diff --git a/website/public/locales/vi/index.json b/website/public/locales/vi/index.json index 1c6b5e19..5f2a8088 100644 --- a/website/public/locales/vi/index.json +++ b/website/public/locales/vi/index.json @@ -3,10 +3,18 @@ "blurb1": "Giống như Stable Diffusion với tranh ảnh bằng AI, Open Assistant sẽ làm tương tự như vậy với con chatbot mã nguồn mở mạnh nhất thế giới.", "description": "Chatbot trí tuệ nhân tạo mã nguồn mở, dựa trên mô hình ngôn ngữ lớn của LAION và các tình nguyện.", "faq_items": { - "q0": "Open Assistant bây giờ thế nào rồi?", - "a0": "Dự án này đang trong giai đoạn phát triển, từ những nghiên cứu về sử dụng RLHF (học từ phản hồi con người) trong các mô hình ngôn ngữ lớn.", + "q0": "Dự án Open Assistant bây giờ thế nào rồi?", + "a0": "Dự án này đang trong giai đoạn phát triển, từ những nghiên cứu về sử dụng RLHF (học từ phản hồi con người) trong trí tuệ nhân tạo.", "q1": "Open Assistant được phát triển bởi ai?", - "a1": "Open Assistant là dự ản được phát triển bởi LAION and các tình nguyện viên." + "a1": "Open Assistant là dự ản được phát triển bởi LAION and các tình nguyện viên.", + "q2": "Open Assistant sẽ sử dụng giấy phép gì?", + "a2": "Mã nguồn và phần mềm trí tuệ nhân tạo sẽ được phát hành dưới giấy phép the Apache 2.0.", + "q3": "Khi nào thì tôi sẽ có dữ liệu?", + "a3": "Sắp, dữ liệu sẽ phát hành dưới giấy phép CC BY 4.0.", + "q4": "Tôi tải về Open Assistant được không?", + "a4": "Yes, Open Assistant là phần mềm mã nguồn mở cho phép người dùng thích làm gì thì làm, miễn là theo giấy phép.", + "q5": "Máy tính phải mạnh đến mức nào thì mới chạy được Open Assistant?", + "a5": "Sẽ có phiên bản mà chạy được trên PC bình thường." }, "faq_title": "Câu hỏi", "join_us_description": "Các dự án mã nguồn mở được phát triển bởi những người như bạn. Triết lý mã nguồn mở là hợp tác để tạo và phát triển công nghệ mới mà làm giàu thế giới quanh ta. Bạn có muốn tham gia không? Liên hệ chúng tôi ở đây:", diff --git a/website/public/locales/vi/leaderboard.json b/website/public/locales/vi/leaderboard.json index d5b4e167..d32ac203 100644 --- a/website/public/locales/vi/leaderboard.json +++ b/website/public/locales/vi/leaderboard.json @@ -1,18 +1,33 @@ { - "daily": "Ngày", + "accepted": "↪ Vào bộ dữ liệu", + "accepted_prompts": "Câu đầu được vào bộ dữ liệu", + "daily": "Theo ngày", + "day": "Theo ngày", + "good_rankings": "Xếp hạng số lần like", "label": "Số nhãn", + "labels_full": "Số nhãn đầy đủ", + "labels_simple": "Số nhãn đã lược giản", "last_updated_at": "Cập nhật lần cuối: {{val, datetime}}", "leaderboard": "Bảng xếp hạng", - "monthly": "Tháng", + "month": "Theo tháng", + "monthly": "Theo tháng", "next": "Tiếp", "overall": "Tổng quan", "previous": "Trước", "prompt": "Số câu đầu", "rank": "Xếp hạng", + "rankings": "Số lần sắp xếp", + "replies_assistant": "Số tin nhắn trợ lý", + "replies_prompter": "Số tin nhắn người dùng", "reply": "Số câu trả lời", + "reply_ranked_1": "Số tin nhắn được đánh giá số 1", "score": "Điểm", "top_5_contributors_today": "Top 5 người đóng góp", + "total": "Tổng", "user": "Tên người dùng", "view_all": "Nhìn tất cả", - "weekly": "Tuần" + "week": "Theo tuần", + "weekly": "Theo tuần", + "your_account": "Tài khoản", + "your_stats": "Thống kê" } diff --git a/website/public/locales/vi/tasks.json b/website/public/locales/vi/tasks.json index 7884f5fe..17d00fd1 100644 --- a/website/public/locales/vi/tasks.json +++ b/website/public/locales/vi/tasks.json @@ -1,5 +1,4 @@ { - "available_task_count": "{{count}} việc", "classify_assistant_reply": { "label": "Phân loại các tin nhắn của Open Assistant", "desc": "Tạo nhãn dữ liệu để đánh giá tin nhắn.", @@ -78,5 +77,8 @@ "overview": "Tạo câu trả lời phù hợp cho cuộc trò truyện dưới đây", "instruction": "Viết tin nhắn trả lời", "response_placeholder": "Viết vào đây..." - } + }, + "available_task_count": "{{count}} việc", + "writing_wrong_langauge_a_b": "Tin nhắn có vẻ được viết trong ngôn ngữ {{detected_lang}} nhưng sẽ được gửi đi là ngôn ngữ {{submit_lang}}.", + "submitted_as": "Câu trả lời sẽ được gửi đi là ngôn ngữ {{submit_lang}}" } From 090c5cbcc24614d6a4d1b09987c7e31aae37dddd Mon Sep 17 00:00:00 2001 From: "jack.butler" Date: Thu, 9 Feb 2023 18:47:38 +0000 Subject: [PATCH 20/54] fix tokenizer matching and add tests --- .../supervised_finetuning/tests/test_utils.py | 21 ++++++++++++++++++- model/supervised_finetuning/utils.py | 2 +- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/model/supervised_finetuning/tests/test_utils.py b/model/supervised_finetuning/tests/test_utils.py index ad40e534..96637e98 100644 --- a/model/supervised_finetuning/tests/test_utils.py +++ b/model/supervised_finetuning/tests/test_utils.py @@ -1,9 +1,28 @@ from argparse import Namespace -from utils import get_tokenizer +import pytest +from utils import TOKENIZER_CONFIGS, get_tokenizer, match_tokenizer_name def test_tokenizer(): get_tokenizer(Namespace(model_name="Salesforce/codegen-2B-multi", cache_dir=".cache")) get_tokenizer(Namespace(model_name="facebook/galactica-1.3b", cache_dir=".cache")) get_tokenizer(Namespace(model_name="", cache_dir=".cache")) + + +def test_tokenizer_successful_match(): + for config_name, config in TOKENIZER_CONFIGS: + found_config = match_tokenizer_name(config_name) + assert found_config == config + + +def test_tokenizer_partial_match(): + for config_name, config in TOKENIZER_CONFIGS: + found_config = match_tokenizer_name(config_name[: len(config_name) - 1]) + assert found_config == config + + +def test_tokenizer_failed_match(): + for fake_config_name in ["not-a-model", "fake"]: + with pytest.raises(ValueError): + match_tokenizer_name(fake_config_name) diff --git a/model/supervised_finetuning/utils.py b/model/supervised_finetuning/utils.py index c3b8264f..43ff6c8c 100644 --- a/model/supervised_finetuning/utils.py +++ b/model/supervised_finetuning/utils.py @@ -37,7 +37,7 @@ TOKENIZER_CONFIGS = { def match_tokenizer_name(model_name: str) -> TokenizerConfig: """Match a partial model name to a tokenizer configuration""" - tokenizer_config_matches = [config for name, config in TOKENIZER_CONFIGS.items() if name in model_name] + tokenizer_config_matches = [config for name, config in TOKENIZER_CONFIGS.items() if model_name in name] if not tokenizer_config_matches: raise ValueError(f"Cannot find any tokeniser configuration to match {model_name=}") elif 1 < len(tokenizer_config_matches): From cbf52a7630d09a487535f2daf955407e79f5271f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=B6pf?= Date: Thu, 9 Feb 2023 20:56:43 +0100 Subject: [PATCH 21/54] add notmd to website code owners --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 8929c25b..3f581f5c 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,5 +1,5 @@ * @yk @andreaskoepf -/website/ @fozziethebeat @k-nearest-neighbor @AbdBarho +/website/ @fozziethebeat @k-nearest-neighbor @AbdBarho @notmd /model/ @theblackcat102 @sanagno /copilot/ @fozziethebeat @andreaskoepf @yk /docs/ @andrewm4894 @andreaskoepf @yk From 6c880117f07827de7a6a8a61165186e48330fe77 Mon Sep 17 00:00:00 2001 From: Muhammad AL-Qurishi <120375378+mqurishi@users.noreply.github.com> Date: Fri, 10 Feb 2023 00:15:06 +0300 Subject: [PATCH 22/54] Fix Arabic Translation (#1385) * Update file layout, merge side menu into common * pre-commit checks --- website/public/locales/ar/common.json | 42 +++++----- website/public/locales/ar/dashboard.json | 10 +-- website/public/locales/ar/index.json | 28 +++---- website/public/locales/ar/labelling.json | 38 ++++----- website/public/locales/ar/leaderboard.json | 6 +- website/public/locales/ar/message.json | 18 ++--- website/public/locales/ar/tasks.json | 94 +++++++++++----------- website/public/locales/ar/tos.json | 4 +- 8 files changed, 120 insertions(+), 120 deletions(-) diff --git a/website/public/locales/ar/common.json b/website/public/locales/ar/common.json index b316033a..4749668c 100644 --- a/website/public/locales/ar/common.json +++ b/website/public/locales/ar/common.json @@ -1,36 +1,36 @@ { - "about": "حول", - "account_settings": "حساب", - "admin_dashboard": "لوحة التحكم الإدارية", - "connect": "الاتصال", - "conversational": "ذكاء تحدثي للجميع.", - "copied": "Copied", - "dark_mode": "الوضع الداكن", - "dashboard_home": "الصفحة الرئيسية للإحصائيات", - "dashboard": "لوحة التحكم", + "about": "من نحن", + "account_settings": "اعدادات", + "admin_dashboard": "لوحة التحكم", + "connect": "تواصل", + "conversational": "ذكاء اصطناعي تفاعلي للجميع.", + "copied": "تم النسخ", + "dark_mode": "الوضع الليلي", + "dashboard_home": "الصفحة الرئيسية للوحة المعلومات", + "dashboard": "لوحة المعلومات", "delete": "حذف", "discord": "ديسكورد", - "docs": "وثائق", + "docs": "التوثيق", "github": "جيت هوب (github)", - "leaderboard": "جدول الأوائل", + "leaderboard": "جدول المتصدرين", "legal": "قانوني", - "light_mode": "الوضع المضيء", + "light_mode": "الوضع النهاري", "loading": "جار التحميل...", - "messages_dashboard": "لوحة تحكم الرسائل", - "messages": "رسائل", - "more_information": "مزيد من المعلومات", + "messages_dashboard": "لوحة عرض الرسائل", + "messages": "الرسائل", + "more_information": "المزيد من المعلومات", "no": "لا", "privacy_policy": "سياسة الخصوصية", "report_a_bug": "إبلاغ عن خطأ", "sign_in": "تسجيل الدخول", "sign_out": "تسجيل الخروج", - "status_dashboard": "لوحة تحكم الحالة", + "status_dashboard": "لوحة عرض الحالة", "status": "الحالة", - "success": "Success", + "success": "نجاح", "terms_of_service": "شروط الخدمة", - "title": "Open Assistant (المساعد المفتوح)", - "user_leaderboard": "جدول الأوائل للمستخدمين", - "users_dashboard": "لوحة تحكم المستخدمين", - "users": "المستخدمون", + "title": "Open Assistant (المساعد مفتوح المصدر)", + "user_leaderboard": "جدول المتصدرين من المستخدمين", + "users_dashboard": "لوحة عرض المستخدمين", + "users": "المستخدمين", "yes": "نعم" } diff --git a/website/public/locales/ar/dashboard.json b/website/public/locales/ar/dashboard.json index d87be0d1..faeeb42c 100644 --- a/website/public/locales/ar/dashboard.json +++ b/website/public/locales/ar/dashboard.json @@ -1,8 +1,8 @@ { - "create": "خلق", - "dashboard": "لوحة التحكم", + "create": "انشاء", + "dashboard": "لوحة المعلومات", "evaluate": "تقييم", - "go": "ذهاب", - "grab_a_task": "التقاط مهمة!", - "label": "تصنيف" + "go": "ذهاب الى", + "grab_a_task": "ابدأ مهمة!", + "label": "وسم" } diff --git a/website/public/locales/ar/index.json b/website/public/locales/ar/index.json index 01f1283d..ab687978 100644 --- a/website/public/locales/ar/index.json +++ b/website/public/locales/ar/index.json @@ -1,23 +1,23 @@ { - "blurb": "نحن نعتقد أنه يمكن أن نخلق ثورة.", - "blurb1": "كما ساهم Stable Diffusion في تحويل عالم الصناعة الفنية والبصرية بتقديم طرق جديدة، نحرص على تحسين العالم من خلال تقديم ذكاء تحدثي عالي الجودة.", - "description": " هدفنا انشاء ذكاء تحدثي عالي الجودة للجميع. لتحقيق هذا الهدف انشانا هذا المشروع مفتوح المصدر للدردشة الاسطناعية تزعمه ليون LAION باهانة مساهمين من كل أنحاء العالم. ", + "blurb": "نؤمن انه بامكاننا ان نصنع ثورة", + "blurb1": "كما ساعد ستايبل ديفيوجن العالم في انشاء فنوف وصور بطرق جديدة, نريد ان نطوره من خلال الذكاء التفاعلي المذهل", + "description": "الذكاء الاصطناعي التفاعلي للجميع , مشروع مفتوح المصدر تم انشائه بواسطة LAION واخرين من جميع انحاء العالم من اجل بناء دردشة معتمدة على النموذج اللغوي المشهور GPT", "faq_items": { - "q0": "إلي أي مدى وصل هذا المشروع؟", - "a0": "نحن في المراحل الأولى من التطوير، نعمل على أساس أبحاث مؤرخة في تطبيق RLHF على النماذج اللغوية الكبيرة.", - "q1": "من وراء Open Assistant؟", - "a1": "Open Assistant هو مشروع منظم من قبل LAION وأفراد من حول العالم يهتمون بجلب هذه التكنولوجيا للجميع.", - "q2": "ما هي الترخيص الذي يستخدمه Open Assistant؟", - "a2": "يتم ترخيص الشفرة والنماذج بموجب ترخيص Apache 2.0.", - "q3": "هل سيتم إصدار بيانات التدريب أيضًا؟", + "q0": "ما هو تقدم المشروع حتى الان؟", + "a0": "نحن في المراحل الأولى من التطوير , نعمل بدأ من الأبحاث المؤكدة في تطبيق RLHFعلى موديلات اللغة الكبيرة ", + "q1": "من الذين يعملون على المساعد مفتوح المصدر", + "a1": "المساعد المفتوح المصدر هو مشروع منظم من قبل LAION وافراد من حول العالم مهتمين بتوفير هذه التقنية للجميع", + "q2": "؟ما هو الترخيص الذي يستخدمه المساعد الفتوح", + "a2": "تم ترخيص الكود والموديلات تحت ترخيص Apache 2.0", + "q3": "هل سيتم نشر بيانات التدريب أيضًا؟", "a3": "نعم، بموجب ترخيص CC BY 4.0.", - "q4": "هل سيكون Open Assistant مجانيًا؟", - "a4": "نعم، سيكون Open Assistant مجانيًا للاستخدام والتعديل.", - "q5": "ما هو الجهاز المطلوب لتشغيل النماذج؟", + "q4": "هل سيكون المساعد المفتوح مجانيًا؟", + "a4": "نعم، سيكون المساعد المفتوح مجانيً للاستخدام والتعديل.", + "q5": "ما هو العتاد المطلوب لتشغيل الموديلات؟", "a5": "سيكون هناك إصدارات يمكن تشغيلها على الأجهزة المصممة للمستهلكين." }, "faq_title": "أسئلة وأجوبة شائعة", "join_us_description": "جميع المشاريع المفتوحة المصدر تبدأ بأشخاص مثلك. المصدر المفتوح هو الإيمان بأنه إذا تعاوننا، يمكن أن نقدم معا علمنا وتكنولوجيتنا لنفع البشرية. هل تريد الانضمام الينا؟ اعثر علينا هنا:", "join_us_title": "انضم إلينا", - "subtitle": "ذكاء تحدثي للجميع." + "subtitle": "ذكاء اصطناعي تفاعلي للجميع." } diff --git a/website/public/locales/ar/labelling.json b/website/public/locales/ar/labelling.json index 34791b2b..c35e2499 100644 --- a/website/public/locales/ar/labelling.json +++ b/website/public/locales/ar/labelling.json @@ -1,24 +1,24 @@ { - "label_highlighted_yes_no_instruction": "أجب على السؤال (الأسئلة) التالي عن الخطاب المميز:", - "label_highlighted_flag_instruction": "حدد أي خيار ينطبق على الخطاب المميز:", - "label_highlighted_likert_instruction": "تقييم الخطاب المميز:", - "label_message_yes_no_instruction": "أجب على السؤال (الأسئلة) التالي عن الخطاب:", - "label_message_flag_instruction": "حدد أي خيار ينطبق على الخطاب:", - "label_message_likert_instruction": "تقييم الخطاب:", - "spam.question": "هل الخطاب هو رسالة غير مرغوب فيها(SPAM)؟", - "fails_task.question": "هل هو رد سيئ، كجواب على النداء؟", - "hate_speech": "نشاط عدائي", - "hate_speech.explanation": "المحتوى يحمل عبارات تشهير أو تهديد ويعبر عن الطائفية ضد خاصية محمية. الطائفية تعني الآراء المسبقة التي لا تعتمد على العقل. الخصائص المحمية تشمل الجنس والعرق والدين والميول الجنسية ومثل هذه الخصائص.", + "label_highlighted_yes_no_instruction": "أجب على السؤال (الأسئلة) التالية حول الرسالة المحددة:", + "label_highlighted_flag_instruction": " حدد أي من الخيارات التالية ينطبق على الرسالة المحددة:", + "label_highlighted_likert_instruction": "قيم الرسالة المحددة:", + "label_message_yes_no_instruction": "أجب على السؤال (الأسئلة) التالية حول الرسالة:", + "label_message_flag_instruction": "حدد أي من الخيارات التالية ينطبق على الرسالة:", + "label_message_likert_instruction": "قيم الرسالة:", + "spam.question": "هل الرسالة غير مرغوب فيها؟ (spam)", + "fails_task.question": "هل الرسالة تمثل رد سيئ، كجواب على التساؤل", + "hate_speech": "خطاب كراهية", + "hate_speech.explanation": "المحتوى مسيء أو مهدد ويعبر عن التحيز ضد خاصية محمية. يشير التحيز إلى آراء مسبقة لا تستند إلى سبب. تشمل الخصائص المحمية الجنس ، الجنسية، الدين ، التوجه الجنسي ، او الخصائص المشابهة.", "lang_mismatch": "لغة خاطئة", - "lang_mismatch.explanation": "لم كتب باللغة المحددة حاليا.", - "moral_judgement": "حكم على الأخلاقيات", - "moral_judgement.explanation": "يعبر عن الأخلاقيات.", - "not_appropriate": "غير مناسب", - "not_appropriate.explanation": "غير مناسب لمساعد الحريف.", - "pii": "تحتوي على PII", - "pii.explanation": "تحتوي على معلومات شخصية يمكن تحديد الهوية بها. مثال يشمل تفاصيل اتصال شخصية، رقم ترخيص وغيرها من أرقام الهوية وتفاصيل الحساب المصرفي.", - "political_content": "سياسي", + "lang_mismatch.explanation": "لم يكتب باللغة المختارة حاليا.", + "moral_judgement": "يحكم على الأخلاقيات", + "moral_judgement.explanation": "يعبر عن الحكم على الأخلاقيات.", + "not_appropriate": "غير ملائم", + "not_appropriate.explanation": "غير ملائم لمساعد العميل.", + "pii": "تحتوي على معلومات شخصية", + "pii.explanation": "يحتوي بيانات شخصية , مثل بيانات التواصل الشخصية, الرخصة , او الأرقام التعريفية والبيانات البنكية", + "political_content": "محتوى سياسي", "political_content.explanation": "يعبر عن الآراء السياسية.", - "sexual_content": "المحتوى الجنسي", + "sexual_content": "محتوى جنسي", "sexual_content.explanation": "يحتوي على محتوى جنسي." } diff --git a/website/public/locales/ar/leaderboard.json b/website/public/locales/ar/leaderboard.json index ab37d1a8..fca6b370 100644 --- a/website/public/locales/ar/leaderboard.json +++ b/website/public/locales/ar/leaderboard.json @@ -1,13 +1,13 @@ { "daily": "يومياً", - "label": "العلامات", + "label": "التوسيمات", "last_updated_at": "آخر تحديث في: {{val, datetime}}", - "leaderboard": "الجدول الترتيبي", + "leaderboard": "جدول المتصدرين", "monthly": "شهرياً", "next": "التالي", "overall": "إجمالياً", "previous": "السابق", - "prompt": "المقترحات", + "prompt": "التساؤل", "rank": "الترتيب", "reply": "الردود", "score": "النقاط", diff --git a/website/public/locales/ar/message.json b/website/public/locales/ar/message.json index a007673e..ee22acbc 100644 --- a/website/public/locales/ar/message.json +++ b/website/public/locales/ar/message.json @@ -1,20 +1,20 @@ { - "copy_message_id": "Copy message ID", - "label_action": "تصنيف", - "label_title": "تصنيف", + "copy_message_id": "نسخ معرف الرسالة", + "label_action": "توسيم", + "label_title": "الوسم", "message": "رسالة", - "message_deleted": "Message deleted", + "message_deleted": "تم حذف الرسالة", "open_new_tab_action": "فتح في علامة تبويب جديدة", - "parent": "الأصل", + "parent": "الاب", "reactions": "الردود", "recent_messages": "أحدث الرسائل", "report_action": "تبليغ", - "report_placeholder": "لماذا يجب استعراض هذه الرسالة؟", + "report_placeholder": "لماذا يجب مراجعة هذه الرسالة؟", "report_title": "تبليغ", "send_report": "إرسال", - "stop_tree": "Stop tree", + "stop_tree": "اوقف الشجرة", "submit_labels": "إرسال", - "tree_stopped": "Tree stopped {{id}}", + "tree_stopped": "تم ايقاف الشجرة {{id}}", "view_user": "عرض المستخدم", - "your_recent_messages": "أحدث رسائلك" + "your_recent_messages": "رسائلك الاخيرة" } diff --git a/website/public/locales/ar/tasks.json b/website/public/locales/ar/tasks.json index fdfb2d86..cba248f6 100644 --- a/website/public/locales/ar/tasks.json +++ b/website/public/locales/ar/tasks.json @@ -1,82 +1,82 @@ { - "available_task_count": "{{count}} مهام متاحة", + "available_task_count": "{{count}} مهام متوفرة", "classify_assistant_reply": { "label": "تصنيف رد المساعد", - "desc": "توفير ملصقات للمنادي.", - "overview": "اقرأ المحادثة التالية وثم أجب عن السؤال حول آخر رد في المناقشة." + "desc": "قدم توسيمات لتساؤل", + "overview": "اقرأ المحادثة التالية ومن ثم أجب عن السؤال حول آخر رد في المحادثة." }, "classify_initial_prompt": { - "label": "صنف بداية النداء", - "desc": "أعط علامات للنداء", - "overview": "اقرأ النداء التالي وأجب عن السؤال عنه." + "label": "صنف التساؤل المبدئي", + "desc": "قدم توسيمات لتساؤل", + "overview": "اقرأ التساؤل التالي وأجب عن السؤال حوله." }, "classify_prompter_reply": { - "label": "تصنيف رد المنادي", - "desc": "توفير ملصقات للمنادي.", - "overview": "اقرأ المحادثة التالية وثم أجب عن السؤال حول آخر رد في المناقشة." + "label": "تصنيف رد المتسائل", + "desc": "قدم توسيمات لتساؤل", + "overview": "اقرأ المحادثة التالية ومن ثم أجب عن السؤال حول آخر رد في المحادثة." }, "create_initial_prompt": { - "label": "إنشاء النداء الأولي", - "desc": "أكتب الندائات الأولية لمساعدة Open Assistant على محاولة الرد على الرسائل المتنوعة.", - "overview": "أنشئ رسالة أولية لإرسالها للمساعد", - "instruction": "أعط االندائات الأولية", - "response_placeholder": "اكتب نداءك هنا..." + "label": "إنشاء تساؤلات مبدئية", + "desc": "اكتب تساؤلات مبدئية لمساعدة المساعد مفتوح المصدر في المحاولة على الرد على أنواع مختلفة من الرسائل (التسجيل في السحب)", + "overview": "أنشئ رسالة مبدئية لإرسالها للمساعد", + "instruction": "اكتب التساؤلات المبدئية", + "response_placeholder": "اكتب تساؤلك هنا..." }, "default": { - "unchanged_title": "لا تغير", + "unchanged_title": "لا تغييرات", "unchanged_message": "هل أنت متأكد من أنك تريد المتابعة؟" }, "label_assistant_reply": { - "label": "تصنيف الرد عن طريق المساعد", - "desc": "تقديم تصنيفات للنداء.", - "overview": "بعد النقاش التالي، تقديم تصنيفات للنداء النهائي." + "label": "تصنيف رد المساعد", + "desc": "زود توسيمات لتساؤل", + "overview": "قم بتزويد توسيمات للتساؤل النهائي من المحادثة التالية " }, "label_initial_prompt": { - "label": "تصنيف النداء الأولي", - "desc": "توفير تصنيفات للنداء.", - "overview": "توفير تصنيفات للنداء التالي" + "label": "تصنيف التساؤل المبدئي", + "desc": "قم بتزويد توسيمات لتساؤل.", + "overview": "قم بتزويد توسيمات للتساؤل التالي" }, "label_prompter_reply": { - "label": "تصنيف الرد على النداء", - "desc": "أعط تصنيفات للنداء.", - "overview": "أعط تصنيفات للرد النهائي في المناقشة التالية." + "label": "تصنيف رد المتسائل", + "desc": "قم بتزويد توسيمات لتساؤل.", + "overview": "قم بتزويد توسيمات للتساؤل النهائي من المحادثة التالية " }, "random": { - "label": "أنا أشعر بالحظ", - "desc": "ساعدنا في تحسين Open Assistant ببدء مهمة عشوائية." + "label": "ضربة حظ", + "desc": "ساعدنا في تحسين المساعد مفتوح المصدر من خلال بدء مهمة عشوائية" }, "rank_assistant_replies": { - "label": "تصنيف ردود المدراء", - "desc": "تصحيح ردود Open Assistant على أساس دقة وقابلية القراءة.", - "overview": "بعد الحصول على الردود التالية للمدراء، قم بترتيبها من أفضل إلى أسوأ، أفضل أولاً وأسوأ آخراً.", - "unchanged_title": "لم يتغير الترتيب", - "unchanged_message": " لم تغير ترتيب المحاور.هل أنت متأكدأنك تريد المواصلة؟" + "label": "رتب ردود المساعد", + "desc": "اعط درجة لردود المساعد مفتوح المصدر على أساس الدقة وقابلية القراءة.", + "overview": "قم بترتيب الردود التالية من المساعد من الافضل الى الاسوء , الافضل اولا والاسوء اخيرا", + "unchanged_title": "لم يتم تغيير الترتيب", + "unchanged_message": " لم تغير ترتيب التساؤلات.هل أنت متأكدأنك تريد المتابعة" }, "rank_initial_prompts": { - "label": "تصنيف النداءات الأولية", - "desc": "تصحيح النداءات المعطاة من قبل Open Assistant على أساس الدقة والقابلية للقراءة.", - "overview": "بالنظر إلى النداءات الأولية التالية، ترتيبها من أفضل إلى أسوأ، أفضل أن يكون أولا، أسوأ أن يكون آخرا.", - "unchanged_title": "لم يتغير الترتيب", - "unchanged_message": "لم تغير ترتيب النداءات. هل أنت متأكد من أنك ترغب في الاستمرار؟" + "label": "رتب التساؤلات المبدئية", + "desc": "قم بترتيب التساؤلات المعطاة من قبل المساعد مفتوح المصدر على أساس الدقة والقابلية للقراءة.", + "overview": "قم بترتيب الردود المبدئية التالية من الافضل الى الاسوء , الافضل اولا والاسوء اخيرا", + "unchanged_title": "لم يتم تغيير الترتيب", + "unchanged_message": " لم تغير ترتيب التساؤلات.هل أنت متأكدأنك تريد المتابعة" }, "rank_user_replies": { - "label": "تصنيف ردود المستخدم", - "desc": "مساعدة Open Assistant لتحسين ردوده على محادثات مع مستخدمين آخرين.", - "overview": "بعد الحصول على الردود التالية للمستخدم، قم بترتيبها من أفضل إلى أسوأ، أفضل أولاً وأسوأ آخراً.", - "unchanged_title": "لم يتغير الترتيب", - "unchanged_message": "لم تقم بتغيير ترتيب الردود. هل أنت متأكد من أن تود الاستمرار؟" + "label": "ترتيب ردود المستخدم", + "desc": "قم بمساعدة المساعد مفتوح المصدر لتحسين ردوده على المحادثات مع المستخدمين الآخرين.", + "overview": "قم بترتيب الردود التالية من المستخدمين من الافضل الى الاسوء , الافضل اولا والاسوء اخيرا", + "unchanged_title": "لم يتم تغيير الترتيب", + "unchanged_message": " لم تغير ترتيب التساؤلات.هل أنت متأكدأنك تريد المتابعة" }, "reply_as_assistant": { - "label": "كــــالمدراء", - "desc": "مساعدة Open Assistant لتحسين ردوده على محادثات مع مستخدمين آخرين.", - "overview": "بعد الحصول على المحادثة التالية، توفير رد كافي", + "label": "رد كالمساعد", + "desc": "قم بمساعدة المساعد مفتوح المصدر لتحسين ردوده على المحادثات مع المستخدمين الآخرين.", + "overview": "قم بتقديم رد مناسب للمحادثة التالية", "response_placeholder": "اكتب ردك هنا..." }, "reply_as_user": { "label": "الرد كمستخدم", - "desc": "تحدث مع Open Assistant وساعده في تحسين ردوده عند التفاعل معه.", - "overview": "بناءً على المحادثة التالية، توفر رد مناسب", - "instruction": "أعط رد المستخدم", + "desc": "تحدث مع المساعد مفتوح المصدر وساعده في تحسين ردوده من خلال التفاعل معه.", + "overview": "قم بتقديم رد مناسب للمحادثة التالية", + "instruction": "اكتب رد المستخدم", "response_placeholder": "اكتب ردك هنا..." } } diff --git a/website/public/locales/ar/tos.json b/website/public/locales/ar/tos.json index 12039a8a..f991b19f 100644 --- a/website/public/locales/ar/tos.json +++ b/website/public/locales/ar/tos.json @@ -1,6 +1,6 @@ { - "title": "شروط الخدمة ل Open Assistant (المساعد المفتوح)", - "content": "للاستمرار في استخدام Open Assistant (المساعد المفتوح)، يجب عليك قبول شروط الخدمة الخاصة بنا أولاً.", + "title": "شروط الخدمة ل Open Assistant (المساعد مفتوح المصدر)", + "content": "للاستمرار في استخدام Open Assistant (المساعد مفتوح المصدر)، يجب عليك قبول شروط الخدمة الخاصة بنا أولاً.", "accept": "قبول", "decline": "رفض" } From 8e323cf87dc50d300ca4097c23ea506cd86cd71e Mon Sep 17 00:00:00 2001 From: Soroush Trb Date: Fri, 10 Feb 2023 00:48:52 +0330 Subject: [PATCH 23/54] added persian language. (#1390) * added persian language * fix persian language * alphabetic --- website/next-i18next.config.js | 1 + website/public/locales/fa/common.json | 38 ++++++++++ website/public/locales/fa/dashboard.json | 8 +++ website/public/locales/fa/index.json | 23 ++++++ website/public/locales/fa/labelling.json | 24 +++++++ website/public/locales/fa/leaderboard.json | 33 +++++++++ website/public/locales/fa/message.json | 21 ++++++ website/public/locales/fa/tasks.json | 84 ++++++++++++++++++++++ website/public/locales/fa/tos.json | 6 ++ 9 files changed, 238 insertions(+) create mode 100644 website/public/locales/fa/common.json create mode 100644 website/public/locales/fa/dashboard.json create mode 100644 website/public/locales/fa/index.json create mode 100644 website/public/locales/fa/labelling.json create mode 100644 website/public/locales/fa/leaderboard.json create mode 100644 website/public/locales/fa/message.json create mode 100644 website/public/locales/fa/tasks.json create mode 100644 website/public/locales/fa/tos.json diff --git a/website/next-i18next.config.js b/website/next-i18next.config.js index 8ae0b222..bc9d8335 100644 --- a/website/next-i18next.config.js +++ b/website/next-i18next.config.js @@ -8,6 +8,7 @@ module.exports = { "de", "en", "es", + "fa", "fr", "hu", "it", diff --git a/website/public/locales/fa/common.json b/website/public/locales/fa/common.json new file mode 100644 index 00000000..4e1f74ca --- /dev/null +++ b/website/public/locales/fa/common.json @@ -0,0 +1,38 @@ +{ + "about": "درباره", + "account_settings": "حساب کاربری", + "admin_dashboard": "داشبورد مدیر", + "connect": "اتصال", + "conversational": "هوش مصنوعی مکالمه برای همه.", + "copied": "کپی شد", + "dark_mode": "حالت تاریک", + "dashboard_home": "خانه داشبورد", + "dashboard": "داشبورد", + "delete": "حذف", + "discord": "دیسکورد", + "docs": "مستندات", + "github": "گیت‌هاب", + "leaderboard": "رده بندی", + "legal": "قانونی", + "light_mode": "حالت روشن", + "loading": "در حال بارگذاری...", + "messages_dashboard": "داشبورد پیام‌ها", + "messages": "پیام‌ها", + "more_information": "اطلاعات بیشتر", + "no": "نه", + "parameters": "مولفه ها", + "privacy_policy": "حریم خصوصی", + "report_a_bug": "گزارش اشکال", + "sign_in": "ورود", + "sign_out": "خروج", + "status": "وضعیت", + "status_dashboard": "داشبورد وضعیت", + "success": "موفقیت", + "terms_of_service": "شرایط استفاده", + "title": "دستیار باز", + "trollboard": "Trollboard", + "user_leaderboard": "رده بندی کاربر", + "users_dashboard": "رده بندی کاربر", + "users": "کاربر", + "yes": "بله" +} diff --git a/website/public/locales/fa/dashboard.json b/website/public/locales/fa/dashboard.json new file mode 100644 index 00000000..8a76bc73 --- /dev/null +++ b/website/public/locales/fa/dashboard.json @@ -0,0 +1,8 @@ +{ + "grab_a_task": "انجام یک کار!", + "create": "ساخت", + "evaluate": "ارزیابی", + "label": "برچسب", + "dashboard": "داشبورد", + "go": "برو" +} diff --git a/website/public/locales/fa/index.json b/website/public/locales/fa/index.json new file mode 100644 index 00000000..95ca824d --- /dev/null +++ b/website/public/locales/fa/index.json @@ -0,0 +1,23 @@ +{ + "blurb": "ما معتقدیم که می توانیم انقلابی ایجاد کنیم.", + "blurb1": "همانطور که Stable Diffusion به جهان کمک کرد تا هنر و تصاویر را به روش های جدید بسازد، ما می خواهیم با ارائه هوش مصنوعی محاوره ای شگفت انگیز جهان را بهبود بخشیم..", + "description": "هوش مصنوعی مکالمه ای برای همه یک پروژه منبع باز برای ایجاد یک گپ فعال GPT LLM که توسط LAION و مشارکت کنندگان در سراسر جهان اجرا می شود.", + "faq_items": { + "q0": "این پروژه چقدر طول می کشد?", + "a0": "ما در مراحل اولیه توسعه هستیم و از تحقیقات تثبیت شده در استفاده از RLHF به مدل های زبانی بزرگ کار می کنیم.", + "q1": "چه کسی پشت دستیار باز است?", + "a1": "دستیار باز پروژه ای است که توسط LAION و افرادی در سراسر جهان که علاقه مند به ارائه این فناوری به همه هستند سازماندهی شده است.", + "q2": "دستیار باز از چه مجوزی استفاده می کند?", + "a2": "کد و مدل ها تحت مجوز Apache 2.0 مجوز هستند.", + "q3": "آیا داده های آموزشی نیز منتشر خواهد شد?", + "a3": "بله, تحت CC BY 4.0.", + "q4": "دستیار باز رایگان خواهد بود?", + "a4": "بله، دستیار باز برای استفاده و اصلاح رایگان خواهد بود.", + "q5": "چه سخت افزاری برای اجرای مدل ها مورد نیاز خواهد بود?", + "a5": "نسخه هایی وجود خواهد داشت که روی سخت افزار همه قابل اجرا خواهند بود." + }, + "faq_title": "سوالات متداول", + "join_us_description": "همه پروژه های متن باز با افرادی مانند شما شروع می شوند. منبع باز این باور است که اگر ما همکاری کنیم، می توانیم با هم دانش و فناوری خود را به نفع بشریت به جهان هدیه کنیم. شما داخل هستید؟ ما را اینجا پیدا کنید:", + "join_us_title": "به ما بپیوندید", + "subtitle": "هوش مصنوعی مکالمه برای همه." +} diff --git a/website/public/locales/fa/labelling.json b/website/public/locales/fa/labelling.json new file mode 100644 index 00000000..26f67447 --- /dev/null +++ b/website/public/locales/fa/labelling.json @@ -0,0 +1,24 @@ +{ + "fails_task.question": "آیا این یک پاسخ بد است، به عنوان پاسخ به کار سریع?", + "hate_speech": "سخنان تنفرآمیز", + "hate_speech.explanation": "محتوا توهین آمیز یا تهدیدآمیز است و بیانگر تعصب نسبت به یک ویژگی محافظت شده است. تعصب به دیدگاه های از پیش تعیین شده ای اشاره دارد که مبتنی بر عقل نیست. ویژگی های محافظت شده شامل جنسیت، قومیت، مذهب، گرایش جنسی و ویژگی های مشابه است.", + "label_highlighted_flag_instruction": "هر کدام را که برای پیام برجسته شده اعمال می شود انتخاب کنید:", + "label_highlighted_likert_instruction": "به پیام هایلایت شده امتیاز دهید:", + "label_highlighted_yes_no_instruction": "به سوال(های) زیر در مورد پیام برجسته شده پاسخ دهید:", + "label_message_flag_instruction": "هر کدام را که برای پیام اعمال می شود انتخاب کنید:", + "label_message_likert_instruction": "به پیام امتیاز دهید:", + "label_message_yes_no_instruction": "به سوال(های) زیر در مورد پیام پاسخ دهید:", + "lang_mismatch": "زبان اشتباه", + "lang_mismatch.explanation": "به زبان انتخابی فعلی نوشته نشده است.", + "moral_judgement": "اخلاقی بودن", + "moral_judgement.explanation": "غیر اخلاقی است.", + "not_appropriate": "نامناسب", + "not_appropriate.explanation": "برای کاربر نامناسب است.", + "pii": "حاوی آشش", + "pii.explanation": "حاوی اطلاعات شناسایی شخصی است. به عنوان مثال می توان به اطلاعات تماس شخصی، مجوز و سایر شماره های هویتی و جزئیات بانکی اشاره کرد.", + "political_content": "سیاسی", + "political_content.explanation": "دیدگاه های سیاسی را بیان می کند.", + "sexual_content": "محتوای جنسی", + "sexual_content.explanation": "حاوی محتوای جنسی.", + "spam.question": "آیا پیام هرزنامه است?" +} diff --git a/website/public/locales/fa/leaderboard.json b/website/public/locales/fa/leaderboard.json new file mode 100644 index 00000000..f4c44ba5 --- /dev/null +++ b/website/public/locales/fa/leaderboard.json @@ -0,0 +1,33 @@ +{ + "daily": "روزانه", + "label": "برچسب ها", + "last_updated_at": "آخرین به روز رسانی در: {{val, datetime}}", + "leaderboard": "رده بندی", + "monthly": "ماهانه", + "next": "بعدی", + "overall": "کلی", + "previous": "قبلی", + "prompt": "درخواست", + "rank": "رتبه", + "reply": "پاسخ", + "score": "امتیاز", + "top_5_contributors_today": "5 مشارکت کننده برتر امروز", + "user": "کاربر", + "view_all": "نمایش همه", + "weekly": "هفتگی", + "accepted": "↪ پذیرفته شده", + "accepted_prompts": "درخواست های پذیرفته شده", + "day": "روز", + "good_rankings": "رتبه های خوب", + "labels_full": "برچسب ها (کامل)", + "labels_simple": "برچسب ها (ساده)", + "month": "ماه", + "rankings": "رتبه بندی", + "replies_assistant": "به عنوان دستیار پاسخ می دهید", + "replies_prompter": "به عنوان درخواست کننده پاسخ می دهید", + "reply_ranked_1": "پاسخ ها در رتبه اول قرار گرفتند", + "total": "کل", + "week": "هفته", + "your_account": "حساب شما", + "your_stats": "آمار شما" +} diff --git a/website/public/locales/fa/message.json b/website/public/locales/fa/message.json new file mode 100644 index 00000000..fbda3535 --- /dev/null +++ b/website/public/locales/fa/message.json @@ -0,0 +1,21 @@ +{ + "copy_message_id": "کپی کردن شناسه پیام", + "copy_message_link": "کپی کردن لینک پیام", + "label_action": "برچسب", + "label_title": "برچسب", + "message_deleted": "پیام پاک شد", + "message": "پیام", + "open_new_tab_action": "بازکردن در صفحه جدید", + "parent": "منبع", + "reactions": "واکنش ها", + "recent_messages": "پیام های اخیر", + "report_action": "گزارش", + "report_placeholder": "چرا باید این پیام بررسی شود?", + "report_title": "گزارش", + "send_report": "ارسال", + "stop_tree": "درخت توقف", + "submit_labels": "ارسال", + "tree_stopped": "درخت متوقف شده در {{id}}", + "view_user": "مشاهده کاربر", + "your_recent_messages": "پیام های اخیر شما" +} diff --git a/website/public/locales/fa/tasks.json b/website/public/locales/fa/tasks.json new file mode 100644 index 00000000..629b2163 --- /dev/null +++ b/website/public/locales/fa/tasks.json @@ -0,0 +1,84 @@ +{ + "default": { + "unchanged_title": "بدون تغییرات", + "unchanged_message": "ادامه میدهید?" + }, + "random": { + "label": "احساس خوش شانسی می کنم", + "desc": "با شروع یک کار تصادفی به ما کمک کنید تا دستیار باز را بهبود ببخشیم." + }, + "create_initial_prompt": { + "label": "درخواست های اولیه را ایجاد کنید", + "desc": "درخواست‌های اولیه را بنویسید تا به دستیار باز کمک کنید تا بتواند به پیام‌های مختلف پاسخ دهد. (شرکت در قرعه کشی)", + "overview": "یک پیام اولیه برای ارسال به دستیار ایجاد کنید", + "instruction": "درخواست های اولیه را ارائه دهید", + "response_placeholder": "درخواست خود را اینجا بنویسید..." + }, + "reply_as_user": { + "label": "به عنوان کاربر پاسخ دهید", + "desc": "با دستیار باز گپ بزنید و در هنگام تعامل با آن به بهبود پاسخ‌های آن کمک کنید.", + "overview": "با توجه به گفتگوی زیر، پاسخ کافی را ارائه دهید", + "instruction": "پاسخ کاربر را ارائه دهید", + "response_placeholder": "پاسخ خود را اینجا بنویسید..." + }, + "reply_as_assistant": { + "label": "به عنوان دستیار پاسخ دهید", + "desc": "به دستیار باز کمک کنید تا پاسخ‌های خود را با سایر کاربران را بهبود بخشد.", + "overview": "با توجه به گفتگوی زیر، پاسخ کافی را ارائه دهید", + "response_placeholder": "پاسخ خود را اینجا بنویسید..." + }, + "rank_user_replies": { + "label": "رتبه‌بندی پاسخ های کاربر", + "desc": "به دستیار باز کمک کنید تا پاسخ‌های خود را با سایر کاربران را بهبود بخشد.", + "overview": "با توجه به پاسخ‌های کاربر زیر، آنها را از بهترین به بدترین، بهترین اول بودن، بدترین آخرین بودن مرتب کنید.", + "unchanged_title": "بدون تغییر", + "unchanged_message": "شما ترتیب درخواست ها را تغییر نداده اید. به ادامه روند مطمئن هستید?" + }, + "rank_assistant_replies": { + "label": "رتبه‌بندی پاسخ های دستیار", + "desc": "اعلان‌های امتیاز توسط دستیار باز بر اساس دقت و خوانایی آن‌ها ارائه می‌شود.", + "overview": "با توجه به پاسخ‌های دستیار زیر، آنها را از بهترین به بدترین، بهترین بودن اولین، بدترین بودن آخرین مرتبه‌سازی کنید.", + "unchanged_title": "بدون تغییر", + "unchanged_message": "شما ترتیب درخواست ها را تغییر نداده اید. به ادامه روند مطمئن هستید?" + }, + "rank_initial_prompts": { + "label": "رتبه‌بندی درخواست های اولیه", + "desc": "اعلان‌های امتیاز توسط دستیار باز بر اساس دقت و خوانایی آن‌ها ارائه می‌شود.", + "overview": "با توجه به دستورات اولیه زیر، آنها را از بهترین به بدترین، بهترین بودن اولین، بدترین بودن آخرین مرتبه سازی کنید..", + "unchanged_title": "بدون تغییر", + "unchanged_message": "شما ترتیب درخواست ها را تغییر نداده اید. به ادامه روند مطمئن هستید?" + }, + "label_initial_prompt": { + "label": "اعلان اولیه را برچسب بزنید", + "desc": "برچسب هایی را برای یک درخواست ارائه دهید.", + "overview": "برای اعلان زیر برچسب ارائه کنید" + }, + "label_prompter_reply": { + "label": "برچسب پاسخ سریع", + "desc": "برچسب هایی را برای یک درخواست ارائه دهید.", + "overview": "با توجه به بحث زیر، برچسب هایی را برای درخواست نهایی ارائه دهید." + }, + "label_assistant_reply": { + "label": "پاسخ دستیار برچسب", + "desc": "برچسب هایی را برای یک درخواست ارائه دهید.", + "overview": "با توجه به بحث زیر، برچسب هایی را برای درخواست نهایی ارائه دهید." + }, + "classify_initial_prompt": { + "label": "طبقه بندی درخواست اولیه", + "desc": "برچسب هایی را برای یک درخواست ارائه دهید.", + "overview": "دستور زیر را بخوانید و سپس به سوال در مورد آن پاسخ دهید." + }, + "classify_prompter_reply": { + "label": "طبقه بندی پاسخ درخواست کننده", + "desc": "برچسب هایی را برای یک درخواست ارائه دهید.", + "overview": "گفتگوی زیر را بخوانید و سپس به سوال در مورد آخرین پاسخ در بحث پاسخ دهید." + }, + "classify_assistant_reply": { + "label": "طبقه بندی پاسخ دستیار", + "desc": "برچسب هایی را برای یک درخواست ارائه دهید.", + "overview": "گفتگوی زیر را بخوانید و سپس به سوال در مورد آخرین پاسخ در بحث پاسخ دهید." + }, + "available_task_count": "{{count}} وظیفه موجود است", + "writing_wrong_langauge_a_b": "بنظر میرسد شما با زبان {{detected_lang}} کار می کنید ولی با زبان {{submit_lang}} ارسال میشود.", + "submitted_as": "با زبان {{submit_lang}} ارسال شد." +} diff --git a/website/public/locales/fa/tos.json b/website/public/locales/fa/tos.json new file mode 100644 index 00000000..c935a9d5 --- /dev/null +++ b/website/public/locales/fa/tos.json @@ -0,0 +1,6 @@ +{ + "title": "شرایط خدمات برای دستیار باز", + "content": "برای ادامه استفاده از دستیار باز ابتدا باید شرایط خدمات ما را بپذیرید.", + "accept": "قبول", + "decline": "رد" +} From 082bf4016205d53acbd729bbd641450e530641a0 Mon Sep 17 00:00:00 2001 From: Ecron Date: Thu, 9 Feb 2023 22:19:35 +0100 Subject: [PATCH 24/54] Fixed some typos in the Catalan translation (#1403) Fixed some typos in the Catalan translation. --- website/public/locales/ca/common.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/website/public/locales/ca/common.json b/website/public/locales/ca/common.json index 23433c15..475f0e5f 100644 --- a/website/public/locales/ca/common.json +++ b/website/public/locales/ca/common.json @@ -1,36 +1,36 @@ { - "about": "Sobre", + "about": "Quant a", "account_settings": "Compte", "admin_dashboard": "Panell d'administració", - "connect": "Connectar", - "conversational": "AI conversacional per a tothom.", + "connect": "Connecta", + "conversational": "IA conversacional per a tothom.", "copied": "Copiat", "dark_mode": "Mode fosc", "dashboard_home": "Panell principal", "dashboard": "Panell principal", - "delete": "Esborrar", + "delete": "Suprimeix", "discord": "Discord", "docs": "Documentació", "github": "GitHub", "leaderboard": "Classificacions", "legal": "Legal", "light_mode": "Mode clar", - "loading": "Carregant...", - "messages_dashboard": "Taulell de missatges", + "loading": "S'està carregant...", + "messages_dashboard": "Panell de missatges", "messages": "Missatges", "more_information": "Més informació", "no": "No", - "privacy_policy": "Política de privacitat", + "privacy_policy": "Política de Privadesa", "report_a_bug": "Informar d'un error", - "sign_in": "Iniciar sessió", - "sign_out": "Tancar sessió", + "sign_in": "Inicia la sessió", + "sign_out": "Tanca la sessió", "success": "Èxit", - "status_dashboard": "Taulell d'estat", + "status_dashboard": "Panell d'estat", "status": "Estat", - "terms_of_service": "Termes de servei", + "terms_of_service": "Condicions del servei", "title": "Open Assistant", "user_leaderboard": "Classificació d'usuaris", - "users_dashboard": "Taulell d'usuaris", + "users_dashboard": "Panell d'usuaris", "users": "Usuaris", "yes": "Sí" } From c24f3c742e147af0461f7da5d6c0e7420f8efa4e Mon Sep 17 00:00:00 2001 From: lytjedk <124836469+lytjedk@users.noreply.github.com> Date: Thu, 9 Feb 2023 22:32:34 +0000 Subject: [PATCH 25/54] Danish #1399 (#1408) * Create dashboard.json * Create index.json * Create labelling.json * Create message.json * Create common.json * Create tos * Create leaderboard.json * Create tasks.json * Update next-i18next.config.js * Update common.json --- website/next-i18next.config.js | 1 + website/public/locales/da/common.json | 38 ++++++++++ website/public/locales/da/index.json | 23 ++++++ website/public/locales/da/labelling.json | 24 +++++++ website/public/locales/da/leaderboard.json | 33 +++++++++ website/public/locales/da/message.json | 21 ++++++ website/public/locales/da/tasks.json | 84 ++++++++++++++++++++++ website/public/locales/da/tos.json | 6 ++ 8 files changed, 230 insertions(+) create mode 100644 website/public/locales/da/common.json create mode 100644 website/public/locales/da/index.json create mode 100644 website/public/locales/da/labelling.json create mode 100644 website/public/locales/da/leaderboard.json create mode 100644 website/public/locales/da/message.json create mode 100644 website/public/locales/da/tasks.json create mode 100644 website/public/locales/da/tos.json diff --git a/website/next-i18next.config.js b/website/next-i18next.config.js index bc9d8335..1767765b 100644 --- a/website/next-i18next.config.js +++ b/website/next-i18next.config.js @@ -5,6 +5,7 @@ module.exports = { "ar", "bn", "ca", + "da", "de", "en", "es", diff --git a/website/public/locales/da/common.json b/website/public/locales/da/common.json new file mode 100644 index 00000000..441e545c --- /dev/null +++ b/website/public/locales/da/common.json @@ -0,0 +1,38 @@ +{ + "about": "Om", + "account_settings": "Konto", + "admin_dashboard": "Administrator Dashboard", + "connect": "Forbind", + "conversational": "Samtalende AI for alle.", + "copied": "Kopieret", + "dark_mode": "Dark Mode", + "dashboard_home": "Dashboard hjem", + "dashboard": "Dashboard", + "delete": "Slet", + "discord": "Discord", + "docs": "Docs", + "github": "GitHub", + "leaderboard": "Leaderboard", + "legal": "Legal", + "light_mode": "Light Mode", + "loading": "Indlæser...", + "messages_dashboard": "Besked dashboard", + "messages": "Beskeder", + "more_information": "Mere information", + "no": "Nej", + "parameters": "Parametre", + "privacy_policy": "Privatlivspolitik", + "report_a_bug": "Andmeld en fejl", + "sign_in": "Logind", + "sign_out": "Logud", + "status": "Status", + "status_dashboard": "Status dashboard", + "success": "Success", + "terms_of_service": "Terms of Service", + "title": "Open Assistant", + "trollboard": "Trollboard", + "user_leaderboard": "Bruger leaderboard", + "users_dashboard": "Brugere dashboard", + "users": "Brugere", + "yes": "Ja" +} diff --git a/website/public/locales/da/index.json b/website/public/locales/da/index.json new file mode 100644 index 00000000..6d1f181a --- /dev/null +++ b/website/public/locales/da/index.json @@ -0,0 +1,23 @@ +{ + "blurb": "Vi tror på at vi kan skabe en revolution.", + "blurb1": "På samme måde som Stable Diffusion hjalp verden med at skabe kunst og billeder på nye måder, vi ønsker at forbedre verden ved at stille en fantastik samtalende AI til rådighed.", + "description": "Samtalende AI for enhver. Et open source project der vil skabe en GPT LMM af LAION og folk fra verden med mulighed for at chatte", + "faq_items": { + "q0": "Hvor langt er dette project nu?", + "a0": "Vi er i de tidlige stadier af udvikling, vi arbejder med at skabe forskning omkring hvordan man anvender RLHF på store sprogmodeller (LLM).", + "q1": "Hvem står bag Open Assistant?", + "a1": "Open Assistant er et projekt af LAION med individuelle folk fra hele verden interesseret i at bringe denne teknologi til enhver.", + "q2": "Hvilken licens bruger Open Assistant", + "a2": "Både kildetekst og modellen er licenseret under Apache 2.0 licensen.", + "q3": "Vil datasættet bruge til at træne AI'en også blive stillet til rådighed?", + "a3": "Ja, under CC BY 4.0.", + "q4": "Will Open Assistant være gratis?", + "a4": "Ja, Open Assistant bliver gratis, både at bruge og ændre.", + "q5": "Hvilken hardware bliver det nødvendigt at have for at køre modellen?", + "a5": "Der vil være modeller som kan gøres på consumer-hardware." + }, + "faq_title": "Frequently Asked Questions / Ofte stillede spørgsmål", + "join_us_description": "Alle open source projekter begynder med folk som dig. Open source er troen på at vi kan samarbejde om at donere viden og teknologi til verden til fordel for hele menneskeheden. Vil du være med? Find os her:", + "join_us_title": "Join us", + "subtitle": "Samtalende AI for enhver." +} diff --git a/website/public/locales/da/labelling.json b/website/public/locales/da/labelling.json new file mode 100644 index 00000000..2d2bff0e --- /dev/null +++ b/website/public/locales/da/labelling.json @@ -0,0 +1,24 @@ +{ + "fails_task.question": "Er det et dårligt svar som et svar på anmodningen?", + "hate_speech": "Hate Speech", + "hate_speech.explanation": "Indholdet er overgreb, truer eller udtrykker fordomme mod et beskyttet karakteristika. Formodemme henviser til forudindtagede holdninger som ikke har hold i virkeligheden. Beskyttede karaktere inkludere køn, etnisitet, religion og seksuel orientering og ligende karakteristika.", + "label_highlighted_flag_instruction": "Vælg de der gælder for den fremhævede besked:", + "label_highlighted_likert_instruction": "Graduer den fremhævede besked:", + "label_highlighted_yes_no_instruction": "Svar på følgende spørgsmål om den fremhævede besked:", + "label_message_flag_instruction": "Vælg de der gælder for beskeden:", + "label_message_likert_instruction": "Graduer beskeden:", + "label_message_yes_no_instruction": "Svar på følgende spørgsmål om beskeden:", + "lang_mismatch": "Ikke {{language}}", + "lang_mismatch.explanation": "Ikke skrevet på {{language}}.", + "moral_judgement": "Bedømmer moral", + "moral_judgement.explanation": "Udtrykker en moralsk bedømmelse.", + "not_appropriate": "Upassende", + "not_appropriate.explanation": "Upassende for en assistent.", + "pii": "Indeholder PII", + "pii.explanation": "Inderholder personlige henførbare information (Personally Identifying Information). Det kunne f.eks. være kontaktoplysninger, kørekort, CPR-nummer, bankoplysninger etc.", + "political_content": "Politisk", + "political_content.explanation": "Udtrykker politisk holdning.", + "sexual_content": "Seksuelt indhold", + "sexual_content.explanation": "Indeholder sexuelt indhold.", + "spam.question": "Er denne besked spam?" +} diff --git a/website/public/locales/da/leaderboard.json b/website/public/locales/da/leaderboard.json new file mode 100644 index 00000000..294a4adc --- /dev/null +++ b/website/public/locales/da/leaderboard.json @@ -0,0 +1,33 @@ +{ + "accepted": "↪ Accepteret", + "accepted_prompts": "Accepteret prompter", + "daily": "Daglig", + "day": "Dag", + "good_rankings": "Rangliste", + "label": "Labels", + "labels_full": "Labels (fulde)", + "labels_simple": "Labels (simple)", + "last_updated_at": "Sidst opdateret: {{val, datetime}}", + "leaderboard": "Leaderboard", + "month": "Måned", + "monthly": "Månedlig", + "next": "Næste", + "overall": "Overordnet", + "previous": "Forrige", + "prompt": "Prompter", + "rank": "Placering", + "rankings": "Placeringer", + "replies_assistant": "Svar som Assistant", + "replies_prompter": "Svar som Prompter", + "reply": "Svar", + "reply_ranked_1": "Svar på bedste placering", + "score": "Score", + "top_5_contributors_today": "Top 5 bidragsydere i dag", + "total": "Total", + "user": "Bruger", + "view_all": "Se alt", + "week": "Uge", + "weekly": "Ugentlig", + "your_account": "Din konto", + "your_stats": "Din statistik" +} diff --git a/website/public/locales/da/message.json b/website/public/locales/da/message.json new file mode 100644 index 00000000..864a5306 --- /dev/null +++ b/website/public/locales/da/message.json @@ -0,0 +1,21 @@ +{ + "copy_message_id": "Kopier besked ID", + "copy_message_link": "Kopier besked link", + "label_action": "Label", + "label_title": "Label", + "message_deleted": "Besked slettet", + "message": "Besked", + "open_new_tab_action": "Åben i en ny tab", + "parent": "Forælder", + "reactions": "Reaktion", + "recent_messages": "Nylige beskeder", + "report_action": "Anmeld", + "report_placeholder": "Hvorfor skal denne besked vurderes?", + "report_title": "Anmeld", + "send_report": "Indsend", + "stop_tree": "Stop tree", + "submit_labels": "Indsend", + "tree_stopped": "Tree stopped {{id}}", + "view_user": "Se bruger", + "your_recent_messages": "Dine nye beskeder" +} diff --git a/website/public/locales/da/tasks.json b/website/public/locales/da/tasks.json new file mode 100644 index 00000000..56a5d2f7 --- /dev/null +++ b/website/public/locales/da/tasks.json @@ -0,0 +1,84 @@ +{ + "default": { + "unchanged_title": "Ingen ændringer", + "unchanged_message": "Er du sikker på at du vil fortsætte?" + }, + "random": { + "label": "Jeg føler mig heldig", + "desc": "Hjælp os med at forbedre Open Assistant ved at starte en tilfældig opgave." + }, + "create_initial_prompt": { + "label": "Lav første prompter", + "desc": "Skriv første prompter for at hjælpe Open Assistant med at forsøge at svare på diverse beskeder (Læg i lotteriet)", + "overview": "Skab en første besked til Open Assistant", + "instruction": "Giv den første prompt", + "response_placeholder": "Skriv din prompt here..." + }, + "reply_as_user": { + "label": "Svar som bruger", + "desc": "Chat med Open Assistant og hjælp med at forbedre dens respons når du interagere med den.", + "overview": "Givet følgende samtale, angiv et passende svar", + "instruction": "Angiv brugerens svar", + "response_placeholder": "Skriv dit svar her..." + }, + "reply_as_assistant": { + "label": "Svar som assistent", + "desc": "Hjælp Open assistent forbedre dets svar til samtaler med andre.", + "overview": "Givet følgende samtale, angiv et passende svar", + "response_placeholder": "Skriv dit svar her..." + }, + "rank_user_replies": { + "label": "Ranger bruger svar", + "desc": "Hjælp Open assistent forbedre dets svar til samtaler med andre.", + "overview": "Givet følgende samtale, sorter fra bedst til ringest, med bedst i toppen.", + "unchanged_title": "Rækkefølge uændret", + "unchanged_message": "Du har ikke ændret på prompternes rækkefølge. Er du sikker på at du vil fortsætte?" + }, + "rank_assistant_replies": { + "label": "Ranger assistent svar", + "desc": "Giv point til svar givet af Open Assistant baseret på deres præcision og læsbarhed.", + "overview": "Givet følgende svar, sorter fra bedst til ringest, med bedst i toppen.", + "unchanged_title": "Rækkefølge uændret", + "unchanged_message": "Du har ikke ændret på svarenes rækkefølge. Er du sikker på at du vil fortsætte?" + }, + "rank_initial_prompts": { + "label": "Ranger første prompter", + "desc": "Giv point til prompter givet af Open Assistant baseret på deres præcision og læsbarhed.", + "overview": "Givet følgende første prompter, sorter fra bedst til ringest, med bedst i toppen.", + "unchanged_title": "Rækkefølge uændret", + "unchanged_message": "Du har ikke ændret på prompternes rækkefølge. Er du sikker på at du vil fortsætte?" + }, + "label_initial_prompt": { + "label": "Label første prompt", + "desc": "Angiv labels for en prompt.", + "overview": "Angiv labels for den følgende prompt" + }, + "label_prompter_reply": { + "label": "Label prompter svar", + "desc": "Angiv labels for en prompt.", + "overview": "Givet følgende diskussion, angiv labels for den endelige prompt." + }, + "label_assistant_reply": { + "label": "Label assistent svar", + "desc": "Angiv labels for et svar.", + "overview": "Givet følgende diskussion, angiv labels for den endelige prompt." + }, + "classify_initial_prompt": { + "label": "Klasificer første prompt", + "desc": "Provide labels for en prompt.", + "overview": "Givet følgende prompt svar da på spørgsmål omkring denne." + }, + "classify_prompter_reply": { + "label": "Klassificer promptsvar", + "desc": "Provide labels for a prompt.", + "overview": "Læs den følgende samtale og svar på spørgsmålet omrking det sidste svar i diskussionen." + }, + "classify_assistant_reply": { + "label": "Klassificer assistentens svar", + "desc": "Angiv labels for en prompt.", + "overview": "Læs følgende samtale og svar så på spørgsmål omkring det sidste svar i diskussionen." + }, + "available_task_count": "{{count}} tilgængelige opgaver", + "writing_wrong_langauge_a_b": "Det ser ud til at du skriver på {{detected_lang}} men det bliver lagt ind i {{submit_lang}}.", + "submitted_as": "Dette vil blive lagt ind i {{submit_lang}}" +} diff --git a/website/public/locales/da/tos.json b/website/public/locales/da/tos.json new file mode 100644 index 00000000..718233b1 --- /dev/null +++ b/website/public/locales/da/tos.json @@ -0,0 +1,6 @@ +{ + "title": "Servicebetingelser for Open Assistant", + "content": "For fortsat at bruge Open Assistant, skal du acceptere servicebetingelserne.", + "accept": "Accepter", + "decline": "Afslå" +} From 4076afd0d8d89124056c9a1454de55b80b90111e Mon Sep 17 00:00:00 2001 From: Yannic Kilcher Date: Thu, 9 Feb 2023 23:46:44 +0100 Subject: [PATCH 26/54] added token buffer for catchiing stop sequences --- inference/text-client/__main__.py | 3 + inference/worker/__main__.py | 44 ++++++++------- inference/worker/interface.py | 56 +++++++++++++++++++ inference/worker/requirements.txt | 1 + inference/worker/utils.py | 40 +++++++++++++ .../oasst_shared/schemas/inference.py | 3 + 6 files changed, 126 insertions(+), 21 deletions(-) create mode 100644 inference/worker/interface.py create mode 100644 inference/worker/utils.py diff --git a/inference/text-client/__main__.py b/inference/text-client/__main__.py index 8484978e..e56feaa1 100644 --- a/inference/text-client/__main__.py +++ b/inference/text-client/__main__.py @@ -37,6 +37,9 @@ def main(backend_url: str = "http://127.0.0.1:8000"): data = json.loads(event.data) print(data["token"]["text"], end="", flush=True) print() + except typer.Abort: + typer.echo("Exiting...") + break except Exception: typer.echo("Error, restarting chat...") diff --git a/inference/worker/__main__.py b/inference/worker/__main__.py index cea7f257..2a6514b7 100644 --- a/inference/worker/__main__.py +++ b/inference/worker/__main__.py @@ -1,9 +1,9 @@ -import json - +import interface import rel import requests import sseclient import typer +import utils import websocket from loguru import logger from oasst_shared.schemas import inference, protocol @@ -43,19 +43,12 @@ def main( prompt = prefix + "\n".join(messages) + "\nAssistant:" + parameters = interface.GenerateStreamParameters.from_work_request(work_request) response = requests.post( f"{inference_server_url}/generate_stream", json={ "inputs": prompt, - "parameters": { - "max_new_tokens": work_request.max_new_tokens, - "do_sample": work_request.do_sample, - "top_k": work_request.top_k, - "top_p": work_request.top_p, - "temperature": work_request.temperature, - "seed": work_request.seed, - # "stop": ["\nUser:", "\nAssistant:"], # TODO: make this a bit more workable because it's mutliple tokens - }, + "parameters": parameters.dict(), }, stream=True, headers={"Accept": "text/event-stream"}, @@ -68,26 +61,35 @@ def main( return client = sseclient.SSEClient(response) + stream_response = None + token_buffer = utils.TokenBuffer(stop_sequences=parameters.stop) for event in client.events(): logger.debug(f"Received event: {event}") - data = json.loads(event.data) - if data["generated_text"]: - break - token = data["token"] + stream_response = interface.GenerateStreamResponse.parse_raw(event.data) + token = stream_response.token + for send_token in token_buffer.add(token): + ws.send( + inference.WorkResponsePacket( + token=send_token.to_token_response(), + ).json() + ) + if stream_response is None: + logger.error("No stream response received") + return + + for send_token in token_buffer.finish(reason=stream_response.details.finish_reason): ws.send( inference.WorkResponsePacket( - token=inference.TokenResponse( - text=token["text"], - log_prob=token["logprob"], - token_id=token["id"], - ) + token=send_token.to_token_response(), ).json() ) + ws.send( inference.WorkResponsePacket( is_end=True, generated_text=inference.GeneratedTextResponse( - text=data["generated_text"], + text=stream_response.generated_text, + finish_reason=stream_response.details.finish_reason, ), ).json() ) diff --git a/inference/worker/interface.py b/inference/worker/interface.py new file mode 100644 index 00000000..06a3eac6 --- /dev/null +++ b/inference/worker/interface.py @@ -0,0 +1,56 @@ +from typing import Literal + +import pydantic +from oasst_shared.schemas import inference + + +class GenerateStreamParameters(pydantic.BaseModel): + max_new_tokens: int | None + do_sample: bool | None + top_k: int | None + top_p: float | None + temperature: float | None + repetition_penalty: float | None + seed: int | None + stop: list[str] = ["\nUser:", "\nAssistant:"] # TODO: make this a bit more workable because it's mutliple tokens + details: bool = True + + @staticmethod + def from_work_request(work_request: inference.WorkRequest) -> "GenerateStreamParameters": + return GenerateStreamParameters( + max_new_tokens=work_request.max_new_tokens, + do_sample=work_request.do_sample, + top_k=work_request.top_k, + top_p=work_request.top_p, + temperature=work_request.temperature, + repetition_penalty=work_request.repetition_penalty, + seed=work_request.seed, + ) + + +class Token(pydantic.BaseModel): + text: str + logprob: float + id: int + + def __len__(self) -> int: + return len(self.text) + + def to_token_response(self) -> inference.TokenResponse: + return inference.TokenResponse( + text=self.text, + log_prob=self.logprob, + token_id=self.id, + ) + + +class StreamDetails(pydantic.BaseModel): + generated_tokens: int + seed: int | None + finish_reason: Literal["length", "eos_token", "stop_sequence"] + + +class GenerateStreamResponse(pydantic.BaseModel): + token: Token + generated_text: str | None + details: StreamDetails | None diff --git a/inference/worker/requirements.txt b/inference/worker/requirements.txt index 82169379..3afd3617 100644 --- a/inference/worker/requirements.txt +++ b/inference/worker/requirements.txt @@ -1,4 +1,5 @@ loguru +pydantic rel requests sseclient-py diff --git a/inference/worker/utils.py b/inference/worker/utils.py new file mode 100644 index 00000000..2cababcf --- /dev/null +++ b/inference/worker/utils.py @@ -0,0 +1,40 @@ +import collections +from typing import Literal + +import interface + + +class TokenBuffer: + def __init__(self, stop_sequences: list[str]) -> None: + self.stop_sequences = stop_sequences + self.longest_stop_len = max((len(stop) for stop in stop_sequences), default=0) + self.tokens = collections.deque() + self.token_lens = collections.deque() + self.total_len = 0 + + def add(self, token: interface.Token): + self.tokens.append(token) + self.token_lens.append(len(token)) + self.total_len += len(token) + while True: + if not self.tokens: + break + head_len = self.token_lens[0] + if self.total_len - head_len >= self.longest_stop_len: + token = self.tokens.popleft() + self.token_lens.popleft() + self.total_len -= head_len + yield token + else: + break + + def finish(self, reason: Literal["length", "eos_token", "stop_sequence"]): + if reason == "stop_sequence": + end_sequence = "" + while self.tokens: + end_sequence = self.tokens.pop().text + end_sequence + if end_sequence in self.stop_sequences: + break + yield from self.tokens + else: + yield from self.tokens diff --git a/oasst-shared/oasst_shared/schemas/inference.py b/oasst-shared/oasst_shared/schemas/inference.py index 96b05c7b..1bb89a42 100644 --- a/oasst-shared/oasst_shared/schemas/inference.py +++ b/oasst-shared/oasst_shared/schemas/inference.py @@ -1,4 +1,5 @@ import random +from typing import Literal import pydantic @@ -18,6 +19,7 @@ class WorkRequest(pydantic.BaseModel): top_k: int = 50 top_p: float = 0.9 temperature: float = 1.0 + repetition_penalty: float | None = None class TokenResponse(pydantic.BaseModel): @@ -28,6 +30,7 @@ class TokenResponse(pydantic.BaseModel): class GeneratedTextResponse(pydantic.BaseModel): text: str + finish_reason: Literal["length", "eos_token", "stop_sequence"] class WorkResponsePacket(pydantic.BaseModel): From c44ccd0dd440ce59d975decdce5427cfcc2f72e1 Mon Sep 17 00:00:00 2001 From: GuilleHoardings Date: Thu, 9 Feb 2023 23:49:49 +0100 Subject: [PATCH 27/54] Update Spanish translation (#1407) --- website/public/locales/es/common.json | 4 +++- website/public/locales/es/leaderboard.json | 17 ++++++++++++++++- website/public/locales/es/message.json | 1 + website/public/locales/es/tasks.json | 4 +++- website/public/locales/es/tos.json | 8 ++++---- 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/website/public/locales/es/common.json b/website/public/locales/es/common.json index 23bd5955..4a663534 100644 --- a/website/public/locales/es/common.json +++ b/website/public/locales/es/common.json @@ -20,15 +20,17 @@ "messages": "Mensajes", "more_information": "Más información", "no": "No", + "parameters": "Parámetros", "privacy_policy": "Política de privacidad", "report_a_bug": "Informar de un error", "sign_in": "Iniciar sesión", "sign_out": "Cerrar sesión", - "status_dashboard": "Tablón de estado", "status": "Estado", + "status_dashboard": "Tablón de estado", "success": "Éxito", "terms_of_service": "Términos de servicio", "title": "Open Assistant", + "trollboard": "Tablón de trolls", "user_leaderboard": "Clasificación de usuarios", "users_dashboard": "Tablón de usuarios", "users": "Usuarios", diff --git a/website/public/locales/es/leaderboard.json b/website/public/locales/es/leaderboard.json index 1972e900..bb76060f 100644 --- a/website/public/locales/es/leaderboard.json +++ b/website/public/locales/es/leaderboard.json @@ -1,18 +1,33 @@ { + "accepted": "↪ Aceptadas", + "accepted_prompts": "Indicaciones aceptadas", "daily": "Diario", + "day": "Día", + "good_rankings": "Buenas clasificaciones", "label": "Etiquetas", + "labels_full": "Etiquetas (completas)", + "labels_simple": "Etiquetas (sencillas)", "last_updated_at": "Última actualización: {{val, datetime}}", "leaderboard": "Tabla de clasificación", + "month": "Mes", "monthly": "Mensual", "next": "Siguiente", "overall": "Global", "previous": "Anterior", "prompt": "Indicaciones", "rank": "Posición", + "rankings": "Ordenaciones", + "replies_assistant": "Respuestas como asistente", + "replies_prompter": "Respuestas como apuntador", "reply": "Respuestas", + "reply_ranked_1": "Respuestas clasificadas primeras", "score": "Puntuación", "top_5_contributors_today": "5 mayores contribuidores hoy", + "total": "Total", "user": "Usuario", "view_all": "Ver todos", - "weekly": "Semanal" + "week": "Semana", + "weekly": "Semanal", + "your_account": "Tu cuenta", + "your_stats": "Tus estadísticas" } diff --git a/website/public/locales/es/message.json b/website/public/locales/es/message.json index 081b81f4..b2b3f2f3 100644 --- a/website/public/locales/es/message.json +++ b/website/public/locales/es/message.json @@ -1,5 +1,6 @@ { "copy_message_id": "Copiar ID del mensaje", + "copy_message_link": "Copiar enlace al mensaje", "label_action": "Etiquetar", "label_title": "Etiqueta", "message": "Mensaje", diff --git a/website/public/locales/es/tasks.json b/website/public/locales/es/tasks.json index 1c6a4cc5..da761255 100644 --- a/website/public/locales/es/tasks.json +++ b/website/public/locales/es/tasks.json @@ -78,5 +78,7 @@ "overview": "Dada la conversación siguiente, proporciona una respuesta adecuada", "instruction": "Proporciona la respuesta del usuario", "response_placeholder": "Escribe tu respuesta aquí..." - } + }, + "writing_wrong_langauge_a_b": "Parece que estás escribiendo en {{detected_lang}} pero esto se enviará como {{submit_lang}}.", + "submitted_as": "Esto será enviado como {{submit_lang}}" } diff --git a/website/public/locales/es/tos.json b/website/public/locales/es/tos.json index 4d3d62b4..e02420a4 100644 --- a/website/public/locales/es/tos.json +++ b/website/public/locales/es/tos.json @@ -1,6 +1,6 @@ { - "accept": "Accept", - "content": "To continue using Open Assistant, you have to accept our Terms of Service first.", - "decline": "Decline", - "title": "Terms of Service for Open Assistant" + "accept": "Aceptar", + "content": "Para continuar usando Open Assistant, tienes que aceptar nuestros Términos de Servicio primero.", + "decline": "Rechazar", + "title": "Términos de Servicio para Open Assistant" } From 7be84cccc55ec64c84458c1175e6cdbd9a9c14f2 Mon Sep 17 00:00:00 2001 From: Aditya Purwa Date: Fri, 10 Feb 2023 11:09:54 +0700 Subject: [PATCH 28/54] feat: add Bahasa Indonesia (#1337) Adding Bahasa Indonesia (id-ID) language localization --- website/next-i18next.config.js | 1 + website/public/locales/id/common.json | 38 ++++++++++ website/public/locales/id/dashboard.json | 8 ++ website/public/locales/id/index.json | 23 ++++++ website/public/locales/id/labelling.json | 24 ++++++ website/public/locales/id/leaderboard.json | 33 ++++++++ website/public/locales/id/message.json | 20 +++++ website/public/locales/id/tasks.json | 87 ++++++++++++++++++++++ website/public/locales/id/tos.json | 6 ++ 9 files changed, 240 insertions(+) create mode 100644 website/public/locales/id/common.json create mode 100644 website/public/locales/id/dashboard.json create mode 100644 website/public/locales/id/index.json create mode 100644 website/public/locales/id/labelling.json create mode 100644 website/public/locales/id/leaderboard.json create mode 100644 website/public/locales/id/message.json create mode 100644 website/public/locales/id/tasks.json create mode 100644 website/public/locales/id/tos.json diff --git a/website/next-i18next.config.js b/website/next-i18next.config.js index 1767765b..b97a6061 100644 --- a/website/next-i18next.config.js +++ b/website/next-i18next.config.js @@ -22,6 +22,7 @@ module.exports = { "vi", "zh", "tr", + "id", ], }, }; diff --git a/website/public/locales/id/common.json b/website/public/locales/id/common.json new file mode 100644 index 00000000..c1dee131 --- /dev/null +++ b/website/public/locales/id/common.json @@ -0,0 +1,38 @@ +{ + "about": "Tentang", + "account_settings": "Akun", + "admin_dashboard": "Dasbor Admin", + "connect": "Terhubung", + "conversational": "AI Percakapan untuk semuanya", + "copied": "Disalin", + "dark_mode": "Mode Gelap", + "dashboard_home": "Dasbor Awal", + "dashboard": "Dasbor", + "delete": "Hapus", + "discord": "Discord", + "docs": "Docs", + "github": "GitHub", + "leaderboard": "Papan Peringkat", + "legal": "Legal", + "light_mode": "Mode Terang", + "loading": "Memuat...", + "messages_dashboard": "Dasbor Pesan", + "messages": "Pesan", + "more_information": "Informasi lebih lanjut", + "no": "Tidak", + "parameters": "Parameter", + "privacy_policy": "Kebijakan Privasi", + "report_a_bug": "Laporkan Bug", + "sign_in": "Masuk", + "sign_out": "Keluar", + "status": "Status", + "status_dashboard": "Dasbor Status", + "success": "Sukses", + "terms_of_service": "Syarat Layanan", + "title": "Open Assistant", + "trollboard": "Trollboard", + "user_leaderboard": "Papan Peringkat Pengguna", + "users_dashboard": "Dasbor Pengguna", + "users": "Pengguna", + "yes": "Ya" +} diff --git a/website/public/locales/id/dashboard.json b/website/public/locales/id/dashboard.json new file mode 100644 index 00000000..67da3e30 --- /dev/null +++ b/website/public/locales/id/dashboard.json @@ -0,0 +1,8 @@ +{ + "grab_a_task": "Ambil tugas!", + "create": "Buat", + "evaluate": "Evaluasi", + "label": "Label", + "dashboard": "Dasbor", + "go": "Mulai" +} diff --git a/website/public/locales/id/index.json b/website/public/locales/id/index.json new file mode 100644 index 00000000..25d3440b --- /dev/null +++ b/website/public/locales/id/index.json @@ -0,0 +1,23 @@ +{ + "blurb": "Kami percaya kita dapat memulai revolusi.", + "blurb1": "Dengan cara yang sama Stable Diffusion membantu dunia membuat seni dan gambar dengan cara baru, kami ingin meningkatkan dunia dengan menyediakan AI percakapan yang luar biasa.", + "description": "AI Percakapan untuk semua orang. Proyek sumber terbuka untuk membuat model bahasa yang didukung chat oleh LAION dan kontributor di seluruh dunia.", + "faq_items": { + "q0": "Sampai tahap seperti apa proyek ini?", + "a0": "Kami masih berada pada tahap awal pengembangan, bekerja dengan melakukan penelitian yang sudah ada tentang penerapan RLHF pada model bahasa besar.", + "q1": "Siapa yang berada di belakang Open Assistant?", + "a1": "Open Assistant adalah sebuah proyek yang didirikan oleh LAION dan individu di seluruh dunia yang tertarik untuk membawa teknologi ini kepada semua orang.", + "q2": "Lisensi apa yang digunakan Open Assistant?", + "a2": "Kode dan model dilisensikan di bawah lisensi Apache 2.0.", + "q3": "Apakah data pelatihan juga akan dirilis?", + "a3": "Ya, di bawah CC BY 4.0.", + "q4": "Apakah Open Assistant gratis?", + "a4": "Ya, Open Assistant akan gratis digunakan dan dimodifikasi.", + "q5": "Perangkat keras apa yang dibutuhkan untuk menjalankan model?", + "a5": "Akan ada versi yang dapat dijalankan pada perangkat konsumen." + }, + "faq_title": "Pertanyaan yang Sering Ditanyakan", + "join_us_description": "Semua proyek sumber terbuka dimulai dari orang-orang seperti Anda. Sumber terbuka adalah keyakinan bahwa jika kita bekerja sama, kita bisa bersama-sama memberikan pengetahuan dan teknologi kita kepada dunia demi kebaikan umat manusia. Mau bergabung? Temukan kami di sini:", + "join_us_title": "Bergabunglah bersama kami", + "subtitle": "AI Percakapan untuk semua orang." +} diff --git a/website/public/locales/id/labelling.json b/website/public/locales/id/labelling.json new file mode 100644 index 00000000..785901d4 --- /dev/null +++ b/website/public/locales/id/labelling.json @@ -0,0 +1,24 @@ +{ + "fails_task.question": "Apakah ini jawaban yang buruk untuk menjawab prompt di atas?", + "hate_speech": "Ujaran Kebencian", + "hate_speech.explanation": "Berisi konten yang merusak, mengancam, dan mengekspresikan prasangka buruk atas perihal yang dilindungi hukum. Prasangka dikatakan buruk apabila tidak didukung alasan yang tepat. Perihal yang dilindungi hukum adalah seperti jenis kelamin, etnisitas, agama, orientasi seksual, dan sebagainya.", + "label_highlighted_flag_instruction": "Pilih yang sesuai dengan pesan yang sedang disorot:", + "label_highlighted_likert_instruction": "Nilai pesan yang disorot:", + "label_highlighted_yes_no_instruction": "Jawab pertanyaan berikut terkait dengan pesan yang disorot:", + "label_message_flag_instruction": "Pilih yang sesuai dengan pesan:", + "label_message_likert_instruction": "Nilai pesan:", + "label_message_yes_no_instruction": "Jawab pertanyaan berikut yang terkait dengan pesan:", + "lang_mismatch": "Salah Bahasa", + "lang_mismatch.explanation": "Tidak tertulis sesuai dengan bahasa yang dipilih.", + "moral_judgement": "Moral Penghakiman", + "moral_judgement.explanation": "Berisi penghakiman secara moral.", + "not_appropriate": "Tidak Layak", + "not_appropriate.explanation": "Tidak layak untuk asisten percakapan.", + "pii": "Berisi Data Pribadi", + "pii.explanation": "Berisi informasi yang mungkin bisa digunakan untuk mengidentifikasi seseorang. Seperti, nomor telepon, alamat, nomor induk, dan informasi perbankan.", + "political_content": "Politik", + "political_content.explanation": "Berisi konten politik.", + "sexual_content": "Konten Seksual", + "sexual_content.explanation": "Berisi konten seksual.", + "spam.question": "Apakah ini spam?" +} diff --git a/website/public/locales/id/leaderboard.json b/website/public/locales/id/leaderboard.json new file mode 100644 index 00000000..5468fb4e --- /dev/null +++ b/website/public/locales/id/leaderboard.json @@ -0,0 +1,33 @@ +{ + "accepted": "↪ Diterima", + "accepted_prompts": "Perintah yang diterima", + "daily": "Harian", + "day": "Hari", + "good_rankings": "Peringkat yang baik", + "label": "Label", + "labels_full": "Label (lengkap)", + "labels_simple": "Label (sederhana)", + "last_updated_at": "Terakhir diperbarui: {{val, datetime}}", + "leaderboard": "Papan peringkat", + "month": "Bulan", + "monthly": "Bulanan", + "next": "Selanjutnya", + "overall": "Garis Besar", + "previous": "Sebelumnya", + "prompt": "Perintah", + "rank": "Peringkat", + "rankings": "Peringkat", + "replies_assistant": "Balasan sebagai Asisten", + "replies_prompter": "Balasan sebagai Prompter", + "reply": "Balasan", + "reply_ranked_1": "Balasan yang diberi peringkat 1", + "score": "Skor", + "top_5_contributors_today": "5 Kontributor Teratas Hari Ini", + "total": "Total", + "user": "Pengguna", + "view_all": "Lihat semua", + "week": "Minggu", + "weekly": "Mingguan", + "your_account": "Akun Anda", + "your_stats": "Statistik Anda" +} diff --git a/website/public/locales/id/message.json b/website/public/locales/id/message.json new file mode 100644 index 00000000..f2727076 --- /dev/null +++ b/website/public/locales/id/message.json @@ -0,0 +1,20 @@ +{ + "copy_message_id": "Salin ID Pesan", + "label_action": "Label", + "label_title": "Label", + "message_deleted": "Pesan dihapus", + "message": "Pesan", + "open_new_tab_action": "Buka di tab baru", + "parent": "Induk", + "reactions": "Reaksi", + "recent_messages": "Pesan Terbaru", + "report_action": "Laporkan", + "report_placeholder": "Tuliskan alasan Anda", + "report_title": "Laporkan", + "send_report": "Kirim laporan", + "stop_tree": "Hentikan struktur pohon", + "submit_labels": "Simpan label", + "tree_stopped": "Struktur pohon dihentikan {{id}}", + "view_user": "Lihat pengguna", + "your_recent_messages": "Pesan terbaru Anda" +} diff --git a/website/public/locales/id/tasks.json b/website/public/locales/id/tasks.json new file mode 100644 index 00000000..a2449067 --- /dev/null +++ b/website/public/locales/id/tasks.json @@ -0,0 +1,87 @@ +{ + "default": { + "unchanged_title": "Tidak ada perubahan", + "unchanged_message": "Apakah Anda yakin ingin melanjutkan?" + }, + "random": { + "label": "Saya merasa beruntung", + "desc": "Bantu kami memperbaiki Open Assistant dengan memilih tugas secara acak." + }, + "create_initial_prompt": { + "label": "Buat Prompt Awal", + "desc": "Tulis prompt awal untuk membantu Open Assistant mencoba membalas pesan yang beragam. (masuk ke undian)", + "overview": "Buat pesan awal untuk dikirimkan ke asisten", + "instruction": "Berikan prompt awal", + "response_placeholder": "Tulis prompt Anda di sini..." + }, + "reply_as_user": { + "label": "Balas sebagai Pengguna", + "desc": "Berbicara dengan Open Assistant dan bantu meningkatkan respons dengan berinteraksi dengannya.", + "overview": "Berdasarkan percakapan berikut, berikan balasan yang sesuai", + "instruction": "Berikan balasan pengguna", + "response_placeholder": "Tulis balasan Anda di sini..." + }, + "reply_as_assistant": { + "label": "Balas sebagai Asisten", + "desc": "Bantu Open Assistant memperbaiki respons terhadap percakapan dengan pengguna lain.", + "overview": "Berdasarkan percakapan berikut, berikan balasan yang sesuai", + "response_placeholder": "Tulis balasan Anda di sini..." + }, + "rank_user_replies": { + "label": "Urutkan Balasan Pengguna", + "desc": "Bantu Open Assistant memperbaiki respons terhadap percakapan dengan pengguna lain.", + "overview": "Berdasarkan Balasan Pengguna berikut, urutkan dari yang terbaik ke yang terburuk, yang terbaik pertama dan yang terburuk terakhir.", + "unchanged_title": "Urutan Tidak Berubah", + "unchanged_message": "Anda belum mengubah urutan prompt. Apakah Anda yakin ingin melanjutkan?" + }, + "rank_assistant_replies": { + "label": "Urutkan Balasan Asisten", + "desc": "Skor prompt yang diberikan oleh Open Assistant berdasarkan akurasi dan keterbacaan.", + "overview": "Berdasarkan Balasan Asisten berikut, urutkan dari yang terbaik ke yang terburuk, yang terbaik", + "rank_assistant_replies": { + "label": "Peringkat Balasan Asisten", + "desc": "Penilaian pernyataan oleh Open Assistant berdasarkan akurasi dan kemudahan dibaca.", + "overview": "Berdasarkan balasan Asisten berikut, urutkan dari terbaik ke terburuk, terbaik ada di pertama, terburuk ada di terakhir.", + "unchanged_title": "Urutan Tak Berubah", + "unchanged_message": "Anda belum mengubah urutan pernyataan. Apakah Anda yakin ingin melanjutkan?" + }, + "rank_initial_prompts": { + "label": "Peringkat Pernyataan Awal", + "desc": "Penilaian pernyataan oleh Open Assistant berdasarkan akurasi dan kemudahan dibaca.", + "overview": "Berdasarkan pernyataan awal berikut, urutkan dari terbaik ke terburuk, terbaik ada di pertama, terburuk ada di terakhir.", + "unchanged_title": "Urutan Tak Berubah", + "unchanged_message": "Anda belum mengubah urutan pernyataan. Apakah Anda yakin ingin melanjutkan?" + }, + "label_initial_prompt": { + "label": "Label Pernyataan Awal", + "desc": "Berikan label untuk pernyataan.", + "overview": "Berikan label untuk pernyataan berikut" + }, + "label_prompter_reply": { + "label": "Label Balasan Prompter", + "desc": "Berikan label untuk pernyataan.", + "overview": "Berdasarkan diskusi berikut, berikan label untuk pernyataan akhir." + }, + "label_assistant_reply": { + "label": "Label Balasan Asisten", + "desc": "Berikan label untuk pernyataan.", + "overview": "Berdasarkan diskusi berikut, berikan label untuk pernyataan akhir." + }, + "classify_initial_prompt": { + "label": "Klasifikasi Pernyataan Awal", + "desc": "Berikan label untuk pernyataan.", + "overview": "Baca pernyataan berikut dan kemudian jawab pertanyaan tentang itu." + }, + "classify_prompter_reply": { + "label": "Klasifikasi Balasan Prompter", + "desc": "Berikan label untuk pernyataan.", + "overview": "Baca percakapan berikut dan kemudian jawab pertanyaan tentang balasan terakhir dalam diskusi." + }, + "classify_assistant_reply": { + "label": "Klasifikasi Balasan Asisten", + "desc": "Berikan label untuk pernyataan.", + "overview": "Baca percakapan berikut dan kemudian jawab pertanyaan tentang balasan terakhir dalam diskusi." + }, + "available_task_count": "{{count}} tugas tersedia" + } +} diff --git a/website/public/locales/id/tos.json b/website/public/locales/id/tos.json new file mode 100644 index 00000000..dac71a29 --- /dev/null +++ b/website/public/locales/id/tos.json @@ -0,0 +1,6 @@ +{ + "title": "Syarat dan Ketentuan Penggunaan Open Assistant", + "content": "Untuk melanjutkan menggunakan Open Assistant, anda harus menerima Syarat dan Ketentuan Penggunaan terlebih dahulu.", + "accept": "Terima", + "decline": "Tolak" +} From 8c94eed0a8e4a927171fc00fd6a5d09e99cac8b4 Mon Sep 17 00:00:00 2001 From: OpenEvil___ <122345469+aayojezuzchrezt@users.noreply.github.com> Date: Fri, 10 Feb 2023 07:10:13 +0300 Subject: [PATCH 29/54] Full Russian Translation [Updated] (#1361) Updated locales (synced and translated them after last update). (Not sure if I get "Good rankings", so left original next to translated, might fix it later) --- website/public/locales/ru/common.json | 7 +- website/public/locales/ru/labelling.json | 4 +- website/public/locales/ru/leaderboard.json | 17 +++- website/public/locales/ru/message.json | 9 +- website/public/locales/ru/tasks.json | 106 +++++++++++---------- 5 files changed, 81 insertions(+), 62 deletions(-) diff --git a/website/public/locales/ru/common.json b/website/public/locales/ru/common.json index 7fbf86ee..471bad6b 100644 --- a/website/public/locales/ru/common.json +++ b/website/public/locales/ru/common.json @@ -2,7 +2,7 @@ "about": "О нас", "account_settings": "Аккаунт", "admin_dashboard": "Панель администратора", - "connect": "Подключиться", + "connect": "Присоединиться к нам", "conversational": "Разговорный ИИ для каждого.", "copied": "Скопировано", "dark_mode": "Темная тема", @@ -13,7 +13,7 @@ "docs": "Документация", "github": "GitHub", "leaderboard": "Рейтинг", - "legal": "Legal", + "legal": "Правовая информация", "light_mode": "Светлая тема", "loading": "Загрузка...", "messages_dashboard": "Панель просмотра сообщений", @@ -26,9 +26,10 @@ "sign_out": "Выйти из аккаунта", "status_dashboard": "Панель состояния системы", "status": "Статус", - "success": "Success", + "success": "Успешно", "terms_of_service": "Пользовательское Соглашение", "title": "Open Assistant", + "trollboard": "Доска позора", "user_leaderboard": "Таблица лидеров", "users_dashboard": "Панель управления пользователями", "users": "Пользователи", diff --git a/website/public/locales/ru/labelling.json b/website/public/locales/ru/labelling.json index a2257ff5..cc1073b7 100644 --- a/website/public/locales/ru/labelling.json +++ b/website/public/locales/ru/labelling.json @@ -8,8 +8,8 @@ "label_message_flag_instruction": "Выберите все, что относится к сообщению:", "label_message_likert_instruction": "Оцените сообщение:", "label_message_yes_no_instruction": "Ответьте на следующий вопрос (вопросы) о сообщении:", - "lang_mismatch": "Неправильный язык", - "lang_mismatch.explanation": "Не написано на выбранном языке.", + "lang_mismatch": "Неправильный язык (не {lang})", + "lang_mismatch.explanation": "Не написано на выбранном языке — {lang}.", "moral_judgement": "Оценивает мораль", "moral_judgement.explanation": "Выражает субъективную моральную оценку.", "not_appropriate": "Неуместный ответ", diff --git a/website/public/locales/ru/leaderboard.json b/website/public/locales/ru/leaderboard.json index 77971485..6f7367fa 100644 --- a/website/public/locales/ru/leaderboard.json +++ b/website/public/locales/ru/leaderboard.json @@ -1,18 +1,33 @@ { + "accepted": "↪ Принято", + "accepted_prompts": "Принятые запросы", "daily": "За день", + "day": "День", + "good_rankings": "Хорошо оценённые (Good rankings)", "label": "Теги", + "labels_full": "Теги (полная классификация)", + "labels_simple": "Теги (упрощённая классификация)", "last_updated_at": "Последний раз обновлено: {{val, datetime}}", "leaderboard": "Таблица лидеров", + "month": "Месяц", "monthly": "За месяц", "next": "Вперед", "overall": "Всего", "previous": "Назад", "prompt": "Запросы", "rank": "Позиция", + "rankings": "Сортировка", + "replies_assistant": "Ответы в качестве Ассистиента", + "replies_prompter": "Ответы в качестве Пользователя", "reply": "Ответы", + "reply_ranked_1": "Ваши ответы, оцененные как лучшие", "score": "Счет", "top_5_contributors_today": "Топ 5 Пользователей за Сегодня", + "total": "Всего", "user": "Пользователь", "view_all": "Посмотреть все", - "weekly": "За неделю" + "week": "Неделя", + "weekly": "За неделю", + "your_account": "Аккаунт", + "your_stats": "Статистика" } diff --git a/website/public/locales/ru/message.json b/website/public/locales/ru/message.json index d262b67c..cbb3e8a2 100644 --- a/website/public/locales/ru/message.json +++ b/website/public/locales/ru/message.json @@ -1,5 +1,6 @@ { - "copy_message_id": "Скопировать message ID", + "copy_message_id": "Скопировать \"message ID\"", + "copy_message_link": "Скопировать ссылку на сообщение", "label_action": "Классифицировать", "label_title": "Классифицировать", "message": "Сообщение", @@ -7,14 +8,14 @@ "open_new_tab_action": "Открыть в новой вкладке", "parent": "Родитель", "reactions": "Реакции", - "recent_messages": "Последние Сообщения", + "recent_messages": "Последние Сообщения ({{language}})", "report_action": "Пожаловаться", "report_placeholder": "Почему это сообщение должно быть рассмотрено?", "report_title": "Пожаловаться", "send_report": "Отправить", - "stop_tree": "Stop tree", + "stop_tree": "Завершить граф", "submit_labels": "Отправить", - "tree_stopped": "Tree stopped {{id}}", + "tree_stopped": "Граф завершён {{id}}", "view_user": "О пользователе", "your_recent_messages": "Ваши Последние сообщения" } diff --git a/website/public/locales/ru/tasks.json b/website/public/locales/ru/tasks.json index 8968d1f9..3b6e747b 100644 --- a/website/public/locales/ru/tasks.json +++ b/website/public/locales/ru/tasks.json @@ -1,19 +1,11 @@ { - "available_task_count": "Доступных заданий: {{count}}", - "classify_assistant_reply": { - "label": "Оцените ответ Ассистента", - "desc": "Расставьте метки для запроса.", - "overview": "Прочитайте следующую переписку, а затем ответьте на вопросы о последнем сообщении." + "default": { + "unchanged_title": "Без изменений", + "unchanged_message": "Вы уверены, что хотите продолжить?" }, - "classify_initial_prompt": { - "label": "Оцените исходный запрос", - "desc": "Расставьте метки для запроса.", - "overview": "Прочитайте запрос, а затем ответьте на вопросы о нем." - }, - "classify_prompter_reply": { - "label": "Оцените ответ пользователя", - "desc": "Предоставьте метки для ответа.", - "overview": "Прочитайте следующую переписку, а затем ответьте на вопросы о последнем сообщении." + "random": { + "label": "Мне повезет", + "desc": "Помогите нам улучшить Open Assistant, начав выполнять случайное задание." }, "create_initial_prompt": { "label": "Создать изначальный запрос", @@ -22,28 +14,25 @@ "instruction": "Предоставьте изначальный запрос", "response_placeholder": "Напишите свой запрос здесь..." }, - "default": { - "unchanged_title": "Без изменений", - "unchanged_message": "Вы уверены, что хотите продолжить?" + "reply_as_user": { + "label": "Ответить как пользователь", + "desc": "Общайтесь с Open Assistant и помогайте улучшать его ответы в процессе взаимодействия с ним.", + "overview": "Прочитайте диалог, а затем ответьте от лица пользователя, пожалуйста, постарайтесь отвечать адекватно.", + "instruction": "Напишите от лица пользователя", + "response_placeholder": "Напишите свой ответ..." }, - "label_assistant_reply": { - "label": "Оцените ответ Ассистента", - "desc": "Выберите подходящие метки для ответа Ассистента.", - "overview": "Прочтите диалог, а затем выберите подходящие метки для последнего ответа." + "reply_as_assistant": { + "label": "Ответить как Ассистент", + "desc": "Помогите Open Assistant улучшить свои ответы, отвечая от лица Ассистента.", + "overview": "Прочитайте диалог, а затем ответьте от лица Ассистента, пожалуйста, постарайтесь отвечать адекватно.", + "response_placeholder": "Напишите свой ответ..." }, - "label_initial_prompt": { - "label": "Оцените изначальный запрос", - "desc": "Выберите подходящие метки для запроса.", - "overview": "Выберите подходящие метки для следующего запроса." - }, - "label_prompter_reply": { - "label": "Оцените ответ пользователя", - "desc": "Выберите подходящие метки для ответа.", - "overview": "Прочтите диалог, а затем выберите подходящие метки для последнего ответа." - }, - "random": { - "label": "Мне повезет", - "desc": "Помогите нам улучшить Open Assistant, начав выполнять случайное задание." + "rank_user_replies": { + "label": "Оценить ответы пользователей", + "desc": "Помогите Open Assistant, оценив ответы пользователей.", + "overview": "Учитывая приведённые ответы пользователей, отсортируйте их от лучшего к худшему, лучший — первый, худший — последний.", + "unchanged_title": "Порядок не был изменён", + "unchanged_message": "Вы не изменили порядок ответов. Вы уверены, что хотите продолжить?" }, "rank_assistant_replies": { "label": "Оценить ответы Ассистента", @@ -59,24 +48,37 @@ "unchanged_title": "Порядок не был изменён", "unchanged_message": "Вы не изменили порядок запросов. Вы уверены, что хотите продолжить?" }, - "rank_user_replies": { - "label": "Оценить ответы пользователей", - "desc": "Помогите Open Assistant, оценив ответы пользователей.", - "overview": "Учитывая приведённые ответы пользователей, отсортируйте их от лучшего к худшему, лучший — первый, худший — последний.", - "unchanged_title": "Порядок не был изменён", - "unchanged_message": "Вы не изменили порядок ответов. Вы уверены, что хотите продолжить?" + "label_initial_prompt": { + "label": "Оценить изначальный запрос", + "desc": "Выберите подходящие метки для запроса.", + "overview": "Выберите подходящие метки для следующего запроса." }, - "reply_as_assistant": { - "label": "Ответить как ассистент", - "desc": "Помогите Open Assistant улучшить свои ответы, отвечая от лица Ассистента.", - "overview": "Прочитайте диалог, а затем ответьте от лица Ассистента, пожалуйста, постарайтесь отвечать адекватно.", - "response_placeholder": "Напишите свой ответ..." + "label_prompter_reply": { + "label": "Оценить ответ пользователя", + "desc": "Выберите подходящие метки для ответа.", + "overview": "Прочтите диалог, а затем выберите подходящие метки для последнего ответа." }, - "reply_as_user": { - "label": "Ответить как пользователь", - "desc": "Общайтесь с Open Assistant и помогайте улучшать его ответы в процессе взаимодействия с ним.", - "overview": "Прочитайте диалог, а затем ответьте от лица пользователя, пожалуйста, постарайтесь отвечать адекватно.", - "instruction": "Напишите от лица пользователя", - "response_placeholder": "Напишите свой ответ..." - } + "label_assistant_reply": { + "label": "Оценить ответ Ассистента", + "desc": "Выберите подходящие метки для ответа Ассистента.", + "overview": "Прочтите диалог, а затем выберите подходящие метки для последнего ответа." + }, + "classify_initial_prompt": { + "label": "Оценить исходный запрос", + "desc": "Расставьте метки для запроса.", + "overview": "Прочитайте запрос, а затем ответьте на вопросы о нем." + }, + "classify_prompter_reply": { + "label": "Оценить ответ пользователя", + "desc": "Предоставьте метки для ответа.", + "overview": "Прочитайте следующую переписку, а затем ответьте на вопросы о последнем сообщении." + }, + "classify_assistant_reply": { + "label": "Оценить ответ Ассистента", + "desc": "Расставьте метки для запроса.", + "overview": "Прочитайте следующую переписку, а затем ответьте на вопросы о последнем сообщении." + }, + "available_task_count": "Доступных заданий: {{count}}", + "writing_wrong_langauge_a_b": "Язык вашего текста определён как: {{detected_lang}}, но он будет отображаться как: {{submit_lang}}.", + "submitted_as": "Будет помечено как {{submit_lang}} язык" } From 4ab5f58c88545b00644f6f8f3233447f9a79ccbd Mon Sep 17 00:00:00 2001 From: Julen Etxaniz Date: Fri, 10 Feb 2023 05:20:44 +0100 Subject: [PATCH 30/54] add Basque language support (#1186) Add Basque (eu) language support --- website/next-i18next.config.js | 1 + website/public/locales/eu/common.json | 38 ++++++++++ website/public/locales/eu/dashboard.json | 8 +++ website/public/locales/eu/index.json | 23 ++++++ website/public/locales/eu/labelling.json | 24 +++++++ website/public/locales/eu/leaderboard.json | 33 +++++++++ website/public/locales/eu/message.json | 21 ++++++ website/public/locales/eu/tasks.json | 84 ++++++++++++++++++++++ website/public/locales/eu/tos.json | 6 ++ 9 files changed, 238 insertions(+) create mode 100644 website/public/locales/eu/common.json create mode 100644 website/public/locales/eu/dashboard.json create mode 100644 website/public/locales/eu/index.json create mode 100644 website/public/locales/eu/labelling.json create mode 100644 website/public/locales/eu/leaderboard.json create mode 100644 website/public/locales/eu/message.json create mode 100644 website/public/locales/eu/tasks.json create mode 100644 website/public/locales/eu/tos.json diff --git a/website/next-i18next.config.js b/website/next-i18next.config.js index b97a6061..7eb7649b 100644 --- a/website/next-i18next.config.js +++ b/website/next-i18next.config.js @@ -9,6 +9,7 @@ module.exports = { "de", "en", "es", + "eu", "fa", "fr", "hu", diff --git a/website/public/locales/eu/common.json b/website/public/locales/eu/common.json new file mode 100644 index 00000000..1410ed74 --- /dev/null +++ b/website/public/locales/eu/common.json @@ -0,0 +1,38 @@ +{ + "about": "Honi buruz", + "account_settings": "Kontua", + "admin_dashboard": "Administrazio panela", + "connect": "Konektatu", + "conversational": "Elkarrizketarako AA guztientzat.", + "copied": "Kopiatua", + "dark_mode": "Ilun modua", + "dashboard": "Aginte-panela", + "dashboard_home": "Aginte-panelaren hasiera", + "delete": "Ezabatu", + "discord": "Discord", + "docs": "Dokumentazioa", + "github": "GitHub", + "leaderboard": "Sailkapena", + "legal": "Legea", + "light_mode": "Argi modua", + "loading": "Kargatzen...", + "messages": "Mezuak", + "messages_dashboard": "Mezuen panela", + "more_information": "Informazio gehiago", + "no": "Ez", + "parameters": "Parametroak", + "privacy_policy": "Pribatutasun politika", + "report_a_bug": "Errorea jakinarazi", + "sign_in": "Hasi saioa", + "sign_out": "Amaitu saioa", + "status": "Egoera", + "status_dashboard": "Egoera panela", + "success": "Arrakasta", + "terms_of_service": "Zerbitzuaren baldintzak", + "title": "Open Assistant", + "trollboard": "Troll sailkapena", + "user_leaderboard": "Erabiltzaileen sailkapena", + "users": "Erabiltzaileak", + "users_dashboard": "Erabiltzaileen panela", + "yes": "Bai" +} diff --git a/website/public/locales/eu/dashboard.json b/website/public/locales/eu/dashboard.json new file mode 100644 index 00000000..fd5d377b --- /dev/null +++ b/website/public/locales/eu/dashboard.json @@ -0,0 +1,8 @@ +{ + "create": "Sortu", + "dashboard": "Aginte-panela", + "evaluate": "Ebaluatu", + "go": "Joan", + "grab_a_task": "Hartu zeregin bat!", + "label": "Etiketa" +} diff --git a/website/public/locales/eu/index.json b/website/public/locales/eu/index.json new file mode 100644 index 00000000..4a2ef104 --- /dev/null +++ b/website/public/locales/eu/index.json @@ -0,0 +1,23 @@ +{ + "blurb": "Uste dugu iraultza bat sortu dezakegula.", + "blurb1": "Stable Diffusion-ek munduari artea eta irudiak modu berrietan egiten lagundu zion modu berean, mundua hobetu nahi dugu elkarrizketarako AA harrigarria eskainiz.", + "description": "Elkarrizketarako AA guztientzat. Iturburu irekiko proiektua GPT LLM txat bat sortzeko, LAIONek eta mundu osoko laguntzaileek zuzendua", + "faq_items": { + "q0": "Noraino doa proiektu hau?", + "a0": "Garapenaren hasierako faseetan gaude, RLHF hizkuntza-eredu handiei aplikatzeko ezarritako ikerketatik lanean.", + "q1": "Nor dago Open Assistant-en atzean?", + "a1": "Open Assistant LAIONek eta mundu osoko teknologia hori guztiongana heltzeko interesa duten pertsonek antolatutako proiektua da.", + "q2": "Zer lizentzia erabiltzen du Open Assistant-ek?", + "a2": "Kodea eta ereduak Apache 2.0 lizentziapean daude lizentziatuta.", + "q3": "Entrenamendurako datuak ere kaleratuko al dira?", + "a3": "Bai, CC BY 4.0 lizentziarekin.", + "q4": "Open Assistant doakoa izango al da?", + "a4": "Bai, Open Assistant librea izango da erabiltzeko eta aldatzeko.", + "q5": "Zer hardware beharko da ereduak exekutatzeko?", + "a5": "Kontsumitzaileen hardwarean exekutatu ahal izango diren bertsioak egongo dira." + }, + "faq_title": "Ohiko galderak", + "join_us_description": "Kode irekiko proiektu guztiak zu bezalako jendearekin hasten dira. Kode irekia elkarlanean aritzen bagara elkarrekin gure ezagutzak eta teknologiak gizateriaren mesederako munduari opari ditzakegula ustea da. Barruan al zaude? Aurki gaitzazu hemen:", + "join_us_title": "Bat egin gurekin", + "subtitle": "Elkarrizketarako AA guztientzat." +} diff --git a/website/public/locales/eu/labelling.json b/website/public/locales/eu/labelling.json new file mode 100644 index 00000000..05b691d2 --- /dev/null +++ b/website/public/locales/eu/labelling.json @@ -0,0 +1,24 @@ +{ + "fails_task.question": "Erantzun txarra al da, sarrerako zereginaren erantzun gisa?", + "hate_speech": "Gorroto hizkera", + "hate_speech.explanation": "Edukia abusua edo mehatxagarria da eta babestutako ezaugarri baten aurkako aurreiritziak adierazten ditu. Aurreiritziak arrazonaketan oinarritzen ez diren aurreko ikuspegiak dira. Babestutako ezaugarrien artean generoa, etnia, erlijioa, sexu-orientazioa eta antzeko ezaugarriak daude.", + "label_highlighted_flag_instruction": "Hautatu nabarmendutako mezuari dagokion edozein:", + "label_highlighted_likert_instruction": "Baloratu nabarmendutako mezua:", + "label_highlighted_yes_no_instruction": "Erantzun nabarmendutako mezuari buruzko galdera hau(ek):", + "label_message_flag_instruction": "Hautatu mezuari dagokion edozein:", + "label_message_likert_instruction": "Baloratu mezua:", + "label_message_yes_no_instruction": "Erantzun mezuari buruzko galdera hau(ek):", + "lang_mismatch": "Hizkuntza okerra", + "lang_mismatch.explanation": "Ez dago une honetan hautatutako hizkuntzan idatzita.", + "moral_judgement": "Moraltasuna epaitzen du", + "moral_judgement.explanation": "Epaiketa morala adierazten du.", + "not_appropriate": "Desegokia", + "not_appropriate.explanation": "Desegokia bezero laguntzaile batentzat.", + "pii": "PII dauka", + "pii.explanation": "Pertsonalki identifikatzeko informazioa dauka. Adibidez, harremanetarako datu pertsonalak, lizentzia eta beste identitate-zenbaki batzuk eta banku-datuak daude.", + "political_content": "Politikoa", + "political_content.explanation": "Iritzi politikoak adierazten ditu.", + "sexual_content": "Eduki sexuala", + "sexual_content.explanation": "Eduki sexuala dauka.", + "spam.question": "Mezua spama al da?" +} diff --git a/website/public/locales/eu/leaderboard.json b/website/public/locales/eu/leaderboard.json new file mode 100644 index 00000000..d9a07adb --- /dev/null +++ b/website/public/locales/eu/leaderboard.json @@ -0,0 +1,33 @@ +{ + "accepted": "↪ Onartua", + "accepted_prompts": "Onartutako instrukzioak", + "daily": "Eguekoa", + "day": "Eguna", + "good_rankings": "Sailkapen onak", + "label": "Etiketak", + "labels_full": "Etiketak (osoa)", + "labels_simple": "Etiketak (sinplea)", + "last_updated_at": "Azken eguneratzea: {{val, datetime}}", + "leaderboard": "Sailkapena", + "month": "Hilabetea", + "monthly": "Hilekoa", + "next": "Hurrengoa", + "overall": "Orokorra", + "previous": "Aurrekoa", + "prompt": "Eskaerak", + "rank": "Postua", + "rankings": "Sailkapenak", + "replies_assistant": "Erantzunak asistente bezala", + "replies_prompter": "Erantzunak erabiltzaile bezala", + "reply": "Erantzunak", + "reply_ranked_1": "Lehen postuan sailkatutako erantzunak", + "score": "Puntuazioa", + "top_5_contributors_today": "Gaurko 5 laguntzaile nagusiak", + "total": "Guztira", + "user": "Erabiltzailea", + "view_all": "Ikusi guztiak", + "week": "Astea", + "weekly": "Astekoa", + "your_account": "Zure kontua", + "your_stats": "Zure estatistikak" +} diff --git a/website/public/locales/eu/message.json b/website/public/locales/eu/message.json new file mode 100644 index 00000000..aef68076 --- /dev/null +++ b/website/public/locales/eu/message.json @@ -0,0 +1,21 @@ +{ + "copy_message_id": "Kopiatu mezuaren IDa", + "copy_message_link": "Kopiatu mezuaren esteka", + "label_action": "Etiketatu", + "label_title": "Etiketa", + "message": "Mezua", + "message_deleted": "Mezua ezabatu da", + "open_new_tab_action": "Ireki orri berri batean", + "parent": "Guraso", + "reactions": "Erreakzioak", + "recent_messages": "Azken mezuak", + "report_action": "Salatu", + "report_placeholder": "Zergatik berrikusi behar da mezu hau?", + "report_title": "Txostena", + "send_report": "Bidali", + "stop_tree": "Gelditu zuhaitza", + "submit_labels": "Bidali", + "tree_stopped": "Zuhaitza gelditu da {{id}}", + "view_user": "Ikusi erabiltzailea", + "your_recent_messages": "Zure azken mezuak" +} diff --git a/website/public/locales/eu/tasks.json b/website/public/locales/eu/tasks.json new file mode 100644 index 00000000..aa5ea58d --- /dev/null +++ b/website/public/locales/eu/tasks.json @@ -0,0 +1,84 @@ +{ + "available_task_count": "{{count}} zeregin eskuragarri", + "classify_assistant_reply": { + "desc": "Jarri etiketak instrukzio bati.", + "label": "Sailifikatu Laguntzailea eginbidearen erantzuna", + "overview": "Irakurri hurrengo elkarrizketa eta erantzun elkarrizketako azken erantzunari buruzko galdera." + }, + "classify_initial_prompt": { + "desc": "Jarri etiketak instrukzio bati.", + "label": "Salifikatu hasierako instrukzioa", + "overview": "Irakurri hurrengo instrukzioa eta erantzun horri buruzko galdera." + }, + "classify_prompter_reply": { + "desc": "Jarri etiketak instrukzio bati.", + "label": "Sailifikatu galdetzailearen erantzuna", + "overview": "Irakurri hurrengo elkarrizketa eta erantzun elkarrizketako azken erantzunari buruzko galdera." + }, + "create_initial_prompt": { + "desc": "Idatzi hasierako instrukzioak Open Assistant-i era askotako mezuak erantzuten saia dadin. (sartu loterian)", + "instruction": "Eman hasierako instrukzioak", + "label": "Sortu hasierako instrukzioak", + "overview": "Sortu hasierako mezu bat asistenteari bidaltzeko", + "response_placeholder": "Idatzi zure instrukzioak hemen..." + }, + "default": { + "unchanged_message": "Ziur al zaude jarraitu nahi duzula?", + "unchanged_title": "Ez dago aldaketarik" + }, + "label_assistant_reply": { + "desc": "Jarri etiketak instrukzio bati.", + "label": "Etiketatu asistentearen erantzuna", + "overview": "Ondoko elkarrizketa ikusita, eman etiketak hurrengo instrukzioari." + }, + "label_initial_prompt": { + "desc": "Jarri etiketak instrukzio bati.", + "label": "Etiketatu hasierako instrukzioak", + "overview": "Jarri etiketak hurrengo instrukzioari" + }, + "label_prompter_reply": { + "desc": "Jarri etiketak instrukzio bati.", + "label": "Etiketatu galdetzailearen erantzuna", + "overview": "Ondoko elkarrizketa ikusita, eman etiketak hurrengo instrukzioari." + }, + "random": { + "desc": "Lagun iezaguzu Open Assistant hobetzen ausazko zeregin bat hasiz.", + "label": "Zorionekoa sentitzen naiz" + }, + "rank_assistant_replies": { + "desc": "Open Assistant-ek emandako erantzunak sailkatu zehaztasun eta irakurgarritasunaren arabera.", + "label": "Asistentearen erantzunak sailkatu", + "overview": "Ondoko asistentearen erantzunak ikusita, ordenatu itzazu onenetik txarrenera, onena lehena izanik, txarrena azkena.", + "unchanged_message": "Ez duzu galderen ordena aldatu. Ziur al zaude jarraitu nahi duzula?", + "unchanged_title": "Ordena aldatu gabe" + }, + "rank_initial_prompts": { + "desc": "Open Assistant-ek emandako erantzunak sailkatu zehaztasun eta irakurgarritasunaren arabera.", + "label": "Hasierako instrukzioak sailkatu", + "overview": "Hasierako eskaera hauek ikusita, ordenatu itzazu onenetik txarrenera, onena lehena izanik, txarrena azkena izanik.", + "unchanged_message": "Ez duzu galderen ordena aldatu. Ziur al zaude jarraitu nahi duzula?", + "unchanged_title": "Ordena aldatu gabe" + }, + "rank_user_replies": { + "desc": "Lagundu Open Assistant-ek beste erabiltzaile batzuekin dituen elkarrizketetako erantzunak hobetzen.", + "label": "Erabiltzaileen erantzunak sailkatu", + "overview": "Ondoko erabiltzaileen erantzunak ikusita, ordenatu itzazu onenetik txarrenera, onena lehena izanik, txarrena azkena izatea.", + "unchanged_message": "Ez duzu galderen ordena aldatu. Ziur al zaude jarraitu nahi duzula?", + "unchanged_title": "Ordena aldatu gabe" + }, + "reply_as_assistant": { + "desc": "Lagundu Open Assistant-ek beste erabiltzaile batzuekin dituen elkarrizketetako erantzunak hobetzen.", + "label": "Erantzun asistente gisa", + "overview": "Ondoko elkarrizketa ikusita, eman erantzun egokia", + "response_placeholder": "Idatzi zure erantzuna hemen..." + }, + "reply_as_user": { + "desc": "Txateatu Open Assistant-ekin eta lagundu bere erantzunak hobetzen harekin elkarreraginean.", + "instruction": "Eman erabiltzailearen erantzuna", + "label": "Erantzun erabiltzaile gisa", + "overview": "Ondoko elkarrizketa ikusita, eman erantzun egokia", + "response_placeholder": "Idatzi zure erantzuna hemen..." + }, + "submitted_as": "Hau {{submit_lang}} hizkuntzan bidaliko da ", + "writing_wrong_langauge_a_b": "Ematen du {{detected_lang}} hizkuntzan baina hau {{submit_lang}} hizkuntzan bidaliko da." +} diff --git a/website/public/locales/eu/tos.json b/website/public/locales/eu/tos.json new file mode 100644 index 00000000..2d6485f5 --- /dev/null +++ b/website/public/locales/eu/tos.json @@ -0,0 +1,6 @@ +{ + "accept": "Onartu", + "content": "Open Assistant erabiltzen jarraitzeko, gure zerbitzu-baldintzak onartu behar dituzu lehenik.", + "decline": "Ukatu", + "title": "Open Assistant-en zerbitzu-baldintzak" +} From aaa1276baec0fcf3da4262e3420bf64d8a546b75 Mon Sep 17 00:00:00 2001 From: notmd <33456881+notmd@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:16:26 +0700 Subject: [PATCH 31/54] Admin user management (#1393) part of #1022 Allow updating the show_on_leaderboard field. Add raw JSON of the user object. Add a new user message table. Also fixed style issue: hard to see reaction count when the user also reacted. Rename MessageTable to MessageConversation. --- website/package-lock.json | 18 +++ website/package.json | 1 + .../components/DataTable/DataTableAction.tsx | 10 ++ .../DataTable/useCursorPagination.ts | 40 +++++ website/src/components/JsonCard.tsx | 12 ++ .../components/Messages/AdminMessageTable.tsx | 110 ++++++++++++++ ...es.tsx => MessageConversation.stories.tsx} | 6 +- ...ssageTable.tsx => MessageConversation.tsx} | 4 +- .../Messages/MessageEmojiButton.tsx | 9 +- website/src/components/Tasks/CreateTask.tsx | 4 +- website/src/components/Tasks/EvaluateTask.tsx | 4 +- .../components/Tasks/LabelTask/LabelTask.tsx | 4 +- .../UserMessagesCell/UserMessagesCell.tsx | 40 ----- .../src/components/UserMessagesCell/index.tsx | 1 - website/src/components/UserTable.tsx | 36 +---- website/src/lib/oasst_api_client.ts | 28 +++- website/src/lib/routes.ts | 3 + website/src/pages/admin/manage_user/[id].tsx | 141 +++++++++++++----- website/src/pages/api/admin/update_user.ts | 4 +- website/src/pages/api/admin/user_messages.ts | 18 ++- website/src/pages/messages/index.tsx | 10 +- website/src/styles/Theme/components/Table.ts | 20 +++ website/src/styles/Theme/index.ts | 2 + website/src/types/Conversation.ts | 8 + website/src/types/Users.ts | 4 +- website/src/types/utils.ts | 7 + 26 files changed, 409 insertions(+), 135 deletions(-) create mode 100644 website/src/components/DataTable/DataTableAction.tsx create mode 100644 website/src/components/DataTable/useCursorPagination.ts create mode 100644 website/src/components/JsonCard.tsx create mode 100644 website/src/components/Messages/AdminMessageTable.tsx rename website/src/components/Messages/{MessageTable.stories.tsx => MessageConversation.stories.tsx} (96%) rename website/src/components/Messages/{MessageTable.tsx => MessageConversation.tsx} (79%) delete mode 100644 website/src/components/UserMessagesCell/UserMessagesCell.tsx delete mode 100644 website/src/components/UserMessagesCell/index.tsx create mode 100644 website/src/lib/routes.ts create mode 100644 website/src/styles/Theme/components/Table.ts diff --git a/website/package-lock.json b/website/package-lock.json index 82a24151..9b369be4 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -27,6 +27,7 @@ "axios": "^1.2.1", "boolean": "^3.2.0", "clsx": "^1.2.1", + "date-fns": "^2.29.3", "eslint": "8.29.0", "eslint-config-next": "13.0.6", "eslint-plugin-simple-import-sort": "^8.0.0", @@ -17710,6 +17711,18 @@ "node": ">=12" } }, + "node_modules/date-fns": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/dayjs": { "version": "1.11.7", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", @@ -51947,6 +51960,11 @@ } } }, + "date-fns": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==" + }, "dayjs": { "version": "1.11.7", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", diff --git a/website/package.json b/website/package.json index d685ac0f..bb09c986 100644 --- a/website/package.json +++ b/website/package.json @@ -45,6 +45,7 @@ "axios": "^1.2.1", "boolean": "^3.2.0", "clsx": "^1.2.1", + "date-fns": "^2.29.3", "eslint": "8.29.0", "eslint-config-next": "13.0.6", "eslint-plugin-simple-import-sort": "^8.0.0", diff --git a/website/src/components/DataTable/DataTableAction.tsx b/website/src/components/DataTable/DataTableAction.tsx new file mode 100644 index 00000000..de4f0b72 --- /dev/null +++ b/website/src/components/DataTable/DataTableAction.tsx @@ -0,0 +1,10 @@ +import { forwardRef, IconButton, IconButtonProps } from "@chakra-ui/react"; +import { LucideIcon } from "lucide-react"; + +export type DataTableActionProps = Omit & { icon: LucideIcon }; + +// need to use forwardRef from Charka to support `as` props +// https://chakra-ui.com/community/recipes/as-prop +export const DataTableAction = forwardRef((props: DataTableActionProps, ref) => { + return } ref={ref} />; +}); diff --git a/website/src/components/DataTable/useCursorPagination.ts b/website/src/components/DataTable/useCursorPagination.ts new file mode 100644 index 00000000..28e4396e --- /dev/null +++ b/website/src/components/DataTable/useCursorPagination.ts @@ -0,0 +1,40 @@ +import { useState } from "react"; + +export interface CursorPaginationState { + /** + * The user's `display_name` used for pagination. + */ + cursor: string; + + /** + * The pagination direction. + */ + direction: "forward" | "back"; +} + +export const useCursorPagination = () => { + const [pagination, setPagination] = useState({ cursor: "", direction: "forward" }); + + const toPreviousPage = (data: undefined | { prev?: string; next?: string }) => { + setPagination({ + cursor: data?.prev || "", + direction: "back", + }); + }; + + const toNextPage = (data: undefined | { prev?: string; next?: string }) => { + setPagination({ + cursor: data?.next || "", + direction: "forward", + }); + }; + + const resetCursor = () => setPagination((old) => ({ ...old, cursor: "" })); + + return { + pagination, + toNextPage, + toPreviousPage, + resetCursor, + }; +}; diff --git a/website/src/components/JsonCard.tsx b/website/src/components/JsonCard.tsx new file mode 100644 index 00000000..973977b4 --- /dev/null +++ b/website/src/components/JsonCard.tsx @@ -0,0 +1,12 @@ +import { Card, CardBody } from "@chakra-ui/card"; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const JsonCard = ({ children }: { children: any }) => { + return ( + + +
{JSON.stringify(children, null, 2)}
+
+
+ ); +}; diff --git a/website/src/components/Messages/AdminMessageTable.tsx b/website/src/components/Messages/AdminMessageTable.tsx new file mode 100644 index 00000000..90866459 --- /dev/null +++ b/website/src/components/Messages/AdminMessageTable.tsx @@ -0,0 +1,110 @@ +import { Avatar } from "@chakra-ui/avatar"; +import { Badge, Flex } from "@chakra-ui/layout"; +import { Tooltip } from "@chakra-ui/react"; +import { createColumnHelper } from "@tanstack/table-core"; +import { formatDistanceToNow, formatISO9075 } from "date-fns"; +import { Eye } from "lucide-react"; +import NextLink from "next/link"; +import { ROUTES } from "src/lib/routes"; +import { Message } from "src/types/Conversation"; +import { isKnownEmoji } from "src/types/Emoji"; +import { StrictOmit } from "src/types/utils"; + +import { DataTable, DataTableProps } from "../DataTable/DataTable"; +import { DataTableAction } from "../DataTable/DataTableAction"; +import { MessageEmojiButton } from "./MessageEmojiButton"; + +const columnHelper = createColumnHelper(); + +const columns = [ + columnHelper.accessor("text", { + cell: ({ getValue, row }) => { + const limit = 80; + const text = getValue(); + const renderText = text.length > limit ? `${text.slice(0, limit)}...` : text; + return ( + + + {renderText} + {row.original.deleted && ( + + Deleted + + )} + + ); + }, + }), + columnHelper.accessor("lang", { + header: "Language", + cell: ({ getValue }) => {getValue()}, + }), + columnHelper.accessor("emojis", { + header: "Reactions", + cell: ({ getValue, row }) => { + const emojis = getValue(); + + emojis["+1"] = emojis["+1"] || 0; + emojis["-1"] = emojis["-1"] || 0; + + return ( + + {Object.entries(emojis) + .filter(([emoji]) => isKnownEmoji(emoji)) + .sort(([emoji]) => -emoji) + .map(([emoji, count]) => { + return ( + + ); + })} + + ); + }, + }), + columnHelper.accessor("created_date", { + header: "Date", + cell: ({ getValue }) => { + return {getValue()}; + }, + }), + columnHelper.accessor((row) => row.id, { + header: "Actions", + cell: ({ getValue }) => ( + + ), + }), +]; +// TODO move this to somewhere +const DateDiff = ({ children }: { children: string | Date | number }) => { + const date = new Date(children); + const diff = formatDistanceToNow(date, { addSuffix: true }); + return ( + + {diff} + + ); +}; + +export const AdminMessageTable = (props: StrictOmit, "columns">) => { + return ; +}; diff --git a/website/src/components/Messages/MessageTable.stories.tsx b/website/src/components/Messages/MessageConversation.stories.tsx similarity index 96% rename from website/src/components/Messages/MessageTable.stories.tsx rename to website/src/components/Messages/MessageConversation.stories.tsx index 772d1b52..c6d6acb3 100644 --- a/website/src/components/Messages/MessageTable.stories.tsx +++ b/website/src/components/Messages/MessageConversation.stories.tsx @@ -2,12 +2,12 @@ import { SessionProvider } from "next-auth/react"; import React from "react"; import { Message } from "src/types/Conversation"; -import { MessageTable } from "./MessageTable"; +import { MessageConversation } from "./MessageConversation"; // eslint-disable-next-line import/no-anonymous-default-export export default { title: "Messages/MessageTable", - component: MessageTable, + component: MessageConversation, }; const Template = ({ @@ -21,7 +21,7 @@ const Template = ({ }) => { return ( - ; + ; ); }; diff --git a/website/src/components/Messages/MessageTable.tsx b/website/src/components/Messages/MessageConversation.tsx similarity index 79% rename from website/src/components/Messages/MessageTable.tsx rename to website/src/components/Messages/MessageConversation.tsx index 2d39f346..4efdfb45 100644 --- a/website/src/components/Messages/MessageTable.tsx +++ b/website/src/components/Messages/MessageConversation.tsx @@ -2,13 +2,13 @@ import { Stack } from "@chakra-ui/react"; import { MessageTableEntry } from "src/components/Messages/MessageTableEntry"; import { Message } from "src/types/Conversation"; -interface MessageTableProps { +interface MessageConversationProps { messages: Message[]; enableLink?: boolean; highlightLastMessage?: boolean; } -export function MessageTable({ messages, enableLink, highlightLastMessage }: MessageTableProps) { +export function MessageConversation({ messages, enableLink, highlightLastMessage }: MessageConversationProps) { return ( {messages.map((message, idx) => ( diff --git a/website/src/components/Messages/MessageEmojiButton.tsx b/website/src/components/Messages/MessageEmojiButton.tsx index e3acb3c0..e2cfd569 100644 --- a/website/src/components/Messages/MessageEmojiButton.tsx +++ b/website/src/components/Messages/MessageEmojiButton.tsx @@ -1,4 +1,4 @@ -import { Button } from "@chakra-ui/react"; +import { Button, ButtonProps } from "@chakra-ui/react"; import { useHasRole } from "src/hooks/auth/useHasRole"; import { MessageEmoji } from "src/types/Conversation"; import { emojiIcons } from "src/types/Emoji"; @@ -6,10 +6,11 @@ import { emojiIcons } from "src/types/Emoji"; interface MessageEmojiButtonProps { emoji: MessageEmoji; checked?: boolean; - onClick: () => void; + onClick?: () => void; userIsAuthor: boolean; disabled?: boolean; userReacted: boolean; + sx?: ButtonProps["sx"]; } export const MessageEmojiButton = ({ @@ -19,6 +20,7 @@ export const MessageEmojiButton = ({ userIsAuthor, disabled, userReacted, + sx, }: MessageEmojiButtonProps) => { const EmojiIcon = emojiIcons.get(emoji.name); const isAdmin = useHasRole("admin"); @@ -42,8 +44,9 @@ export const MessageEmojiButton = ({ ":hover": { backgroundColor: isDisabled ? "transparent" : undefined, }, + ...sx, }} - color={isDisabled ? "gray.500" : undefined} + color={isDisabled ? (checked ? "gray.700" : "gray.500") : undefined} > {showCount && {emoji.count}} diff --git a/website/src/components/Tasks/CreateTask.tsx b/website/src/components/Tasks/CreateTask.tsx index 448ad287..ee9b71c1 100644 --- a/website/src/components/Tasks/CreateTask.tsx +++ b/website/src/components/Tasks/CreateTask.tsx @@ -1,7 +1,7 @@ import { Box, Stack, Text, useColorModeValue } from "@chakra-ui/react"; import { useTranslation } from "next-i18next"; import { useState } from "react"; -import { MessageTable } from "src/components/Messages/MessageTable"; +import { MessageConversation } from "src/components/Messages/MessageConversation"; import { TrackedTextarea } from "src/components/Survey/TrackedTextarea"; import { TwoColumnsWithCards } from "src/components/Survey/TwoColumnsWithCards"; import { TaskSurveyProps } from "src/components/Tasks/Task"; @@ -44,7 +44,7 @@ export const CreateTask = ({ {task.type !== TaskType.initial_prompt && ( - + )} diff --git a/website/src/components/Tasks/EvaluateTask.tsx b/website/src/components/Tasks/EvaluateTask.tsx index 2f24e6f1..ee0ba881 100644 --- a/website/src/components/Tasks/EvaluateTask.tsx +++ b/website/src/components/Tasks/EvaluateTask.tsx @@ -1,6 +1,6 @@ import { Box, useColorModeValue } from "@chakra-ui/react"; import { useEffect, useState } from "react"; -import { MessageTable } from "src/components/Messages/MessageTable"; +import { MessageConversation } from "src/components/Messages/MessageConversation"; import { Sortable } from "src/components/Sortable/Sortable"; import { SurveyCard } from "src/components/Survey/SurveyCard"; import { TaskSurveyProps } from "src/components/Tasks/Task"; @@ -47,7 +47,7 @@ export const EvaluateTask = ({ - + - + { - const url = path || "/api/messages/user"; - const { data: messages, isLoading } = useSWR(url, get, { - refreshInterval: 2000, - }); - // TODO(#651): This box coloring and styling is used in multiple places. We - // should factor it into a common ui component. - const boxBgColor = useColorModeValue("white", "gray.700"); - const boxAccentColor = useColorModeValue("gray.200", "gray.900"); - - return ( - - {isLoading ? : } - - ); -}; - -export { UserMessagesCell }; diff --git a/website/src/components/UserMessagesCell/index.tsx b/website/src/components/UserMessagesCell/index.tsx deleted file mode 100644 index c32b1c1f..00000000 --- a/website/src/components/UserMessagesCell/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from "./UserMessagesCell"; diff --git a/website/src/components/UserTable.tsx b/website/src/components/UserTable.tsx index 5c51c585..385c9d06 100644 --- a/website/src/components/UserTable.tsx +++ b/website/src/components/UserTable.tsx @@ -8,18 +8,7 @@ import type { FetchUsersResponse, User } from "src/types/Users"; import useSWR from "swr"; import { DataTable, DataTableColumnDef, FilterItem } from "./DataTable/DataTable"; - -interface Pagination { - /** - * The user's `display_name` used for pagination. - */ - cursor: string; - - /** - * The pagination direction. - */ - direction: "forward" | "back"; -} +import { useCursorPagination } from "./DataTable/useCursorPagination"; const columnHelper = createColumnHelper(); @@ -56,12 +45,13 @@ const columns: DataTableColumnDef[] = [ ]; export const UserTable = memo(function UserTable() { - const [pagination, setPagination] = useState({ cursor: "", direction: "forward" }); + const { pagination, resetCursor, toNextPage, toPreviousPage } = useCursorPagination(); const [filterValues, setFilterValues] = useState([]); const handleFilterValuesChange = (values: FilterItem[]) => { setFilterValues(values); - setPagination((old) => ({ ...old, cursor: "" })); + resetCursor(); }; + // Fetch and save the users. // This follows useSWR's recommendation for simple pagination: // https://swr.vercel.app/docs/pagination#when-to-use-useswr @@ -74,20 +64,6 @@ export const UserTable = memo(function UserTable() { } ); - const toPreviousPage = () => { - setPagination({ - cursor: data?.prev || "", - direction: "back", - }); - }; - - const toNextPage = () => { - setPagination({ - cursor: data?.next || "", - direction: "forward", - }); - }; - return ( @@ -95,8 +71,8 @@ export const UserTable = memo(function UserTable() { data={data?.items || []} columns={columns} caption="Users" - onNextClick={toNextPage} - onPreviousClick={toPreviousPage} + onNextClick={() => toNextPage(data)} + onPreviousClick={() => toPreviousPage(data)} disableNext={!data?.next} disablePrevious={!data?.prev} filterValues={filterValues} diff --git a/website/src/lib/oasst_api_client.ts b/website/src/lib/oasst_api_client.ts index 2ec76c85..a3607323 100644 --- a/website/src/lib/oasst_api_client.ts +++ b/website/src/lib/oasst_api_client.ts @@ -1,4 +1,4 @@ -import type { EmojiOp, Message } from "src/types/Conversation"; +import type { EmojiOp, FetchUserMessagesCursorResponse, Message } from "src/types/Conversation"; import { LeaderboardReply, LeaderboardTimeFrame } from "src/types/Leaderboard"; import type { AvailableTasks } from "src/types/Task"; import { FetchTrollBoardResponse, TrollboardTimeFrame } from "src/types/Trollboard"; @@ -264,11 +264,33 @@ export class OasstApiClient { return this.get(`/api/v1/users/${user_id}/messages`); } + async fetch_user_messages_cursor( + user_id: string, + { + direction, + cursor, + ...rest + }: { include_deleted?: boolean; max_count?: number; cursor?: string; direction: "forward" | "back"; desc?: boolean } + ) { + return this.get(`/api/v1/users/${user_id}/messages/cursor`, { + ...rest, + after: direction === "forward" ? cursor : undefined, + before: direction === "back" ? cursor : undefined, + }); + } + /** * Updates the backend's knowledge about the `user_id`. */ - async set_user_status(user_id: string, is_enabled: boolean, notes: string): Promise { - await this.put(`/api/v1/users/${user_id}?enabled=${is_enabled}¬es=${notes}`); + async set_user_status( + user_id: string, + is_enabled: boolean, + notes: string, + show_on_leaderboard: boolean + ): Promise { + await this.put( + `/api/v1/users/${user_id}?enabled=${is_enabled}¬es=${notes}&show_on_leaderboard=${show_on_leaderboard}` + ); } /** diff --git a/website/src/lib/routes.ts b/website/src/lib/routes.ts new file mode 100644 index 00000000..f85b5a31 --- /dev/null +++ b/website/src/lib/routes.ts @@ -0,0 +1,3 @@ +export const ROUTES = { + ADMIN_MESSAGE_DETAIL: (id: string) => `/admin/messages/${id}`, +}; diff --git a/website/src/pages/admin/manage_user/[id].tsx b/website/src/pages/admin/manage_user/[id].tsx index a68bca16..ee7bcc66 100644 --- a/website/src/pages/admin/manage_user/[id].tsx +++ b/website/src/pages/admin/manage_user/[id].tsx @@ -1,19 +1,39 @@ -import { Button, Card, CardBody, Container, FormControl, FormLabel, Input, Stack, useToast } from "@chakra-ui/react"; -import { InferGetServerSidePropsType } from "next"; +import { + Accordion, + AccordionButton, + AccordionIcon, + AccordionItem, + AccordionPanel, + Box, + Button, + Card, + CardBody, + CardHeader, + Checkbox, + CircularProgress, + FormControl, + FormLabel, + Input, + Stack, + useToast, +} from "@chakra-ui/react"; +import { GetServerSideProps, InferGetServerSidePropsType } from "next"; import Head from "next/head"; -import { useRouter } from "next/router"; -import { useSession } from "next-auth/react"; import { serverSideTranslations } from "next-i18next/serverSideTranslations"; -import { useEffect } from "react"; import { useForm } from "react-hook-form"; +import { AdminArea } from "src/components/AdminArea"; +import { useCursorPagination } from "src/components/DataTable/useCursorPagination"; +import { JsonCard } from "src/components/JsonCard"; import { getAdminLayout } from "src/components/Layout"; +import { AdminMessageTable } from "src/components/Messages/AdminMessageTable"; import { Role, RoleSelect } from "src/components/RoleSelect"; -import { UserMessagesCell } from "src/components/UserMessagesCell"; -import { post } from "src/lib/api"; +import { get, post } from "src/lib/api"; import { userlessApiClient } from "src/lib/oasst_client_factory"; import prisma from "src/lib/prismadb"; +import { FetchUserMessagesCursorResponse } from "src/types/Conversation"; +import { User } from "src/types/Users"; +import useSWRImmutable from "swr/immutable"; import useSWRMutation from "swr/mutation"; - interface UserForm { user_id: string; id: string; @@ -21,33 +41,17 @@ interface UserForm { display_name: string; role: Role; notes: string; + show_on_leaderboard: boolean; } const ManageUser = ({ user }: InferGetServerSidePropsType) => { const toast = useToast(); - const router = useRouter(); - const { data: session, status } = useSession(); - - // Check when the user session is loaded and re-route if the user is not an - // admin. This follows the suggestion by NextJS for handling private pages: - // https://nextjs.org/docs/api-reference/next/router#usage - // - // All admin pages should use the same check and routing steps. - useEffect(() => { - if (status === "loading") { - return; - } - if (session?.user?.role === "admin") { - return; - } - router.push("/"); - }, [router, session, status]); // Trigger to let us update the user's role. Triggers a toast when complete. const { trigger } = useSWRMutation("/api/admin/update_user", post, { onSuccess: () => { toast({ - title: "User Role Updated", + title: "Updated user", status: "success", duration: 1000, isClosable: true, @@ -76,8 +80,8 @@ const ManageUser = ({ user }: InferGetServerSidePropsType - - + +
trigger(data))}> @@ -88,32 +92,97 @@ const ManageUser = ({ user }: InferGetServerSidePropsTypeDisplay Name - + Role - + Notes + + Show on leaderboard + + + + + + + Raw JSON + + + + + {user} + + +
-
- -
+ + + {`User's messages`} + + + + + +
+ ); }; +const UserMessageTable = ({ id }: { id: User["id"] }) => { + const { pagination, toNextPage, toPreviousPage } = useCursorPagination(); + const { data, error, isLoading } = useSWRImmutable( + `/api/admin/user_messages?user=${id}&cursor=${encodeURIComponent(pagination.cursor)}&direction=${ + pagination.direction + }`, + get, + { + keepPreviousData: true, + } + ); + + if (isLoading && !data) { + return ; + } + + if (error) { + return <>Unable to load messages.; + } + + return ( + toNextPage(data)} + onPreviousClick={() => toPreviousPage(data)} + > + ); +}; + /** * Fetch the user's data on the server side when rendering. */ -export async function getServerSideProps({ query, locale }) { - const backend_user = await userlessApiClient.fetch_user(query.id); +export const getServerSideProps: GetServerSideProps<{ user: User }, { id: string }> = async ({ + params, + locale = "en", +}) => { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const backend_user = await userlessApiClient.fetch_user(params!.id as string); + + if (!backend_user) { + return { + notFound: true, + }; + } const local_user = await prisma.user.findUnique({ where: { id: backend_user.id }, select: { @@ -130,7 +199,7 @@ export async function getServerSideProps({ query, locale }) { ...(await serverSideTranslations(locale, ["common"])), }, }; -} +}; ManageUser.getLayout = getAdminLayout; diff --git a/website/src/pages/api/admin/update_user.ts b/website/src/pages/api/admin/update_user.ts index c71159ad..13ee97f5 100644 --- a/website/src/pages/api/admin/update_user.ts +++ b/website/src/pages/api/admin/update_user.ts @@ -6,7 +6,7 @@ import prisma from "src/lib/prismadb"; * Update's the user's data in the database. Accessible only to admins. */ const handler = withRole("admin", async (req, res, token) => { - const { id, auth_method, user_id, notes, role } = req.body; + const { id, auth_method, user_id, notes, role, show_on_leaderboard } = req.body; const oasstApiClient = await createApiClient(token); // If the user is authorized by the web, update their role. @@ -17,7 +17,7 @@ const handler = withRole("admin", async (req, res, token) => { }); } // Tell the backend the user's enabled or not enabled status. - await oasstApiClient.set_user_status(user_id, role !== "banned", notes); + await oasstApiClient.set_user_status(user_id, role !== "banned", notes, show_on_leaderboard); res.status(200).json({}); }); diff --git a/website/src/pages/api/admin/user_messages.ts b/website/src/pages/api/admin/user_messages.ts index 0223e8e3..bca4d0f2 100644 --- a/website/src/pages/api/admin/user_messages.ts +++ b/website/src/pages/api/admin/user_messages.ts @@ -1,15 +1,25 @@ import { withRole } from "src/lib/auth"; import { createApiClient } from "src/lib/oasst_client_factory"; -import type { Message } from "src/types/Conversation"; + +const LIMIT = 10; /** * Returns the messages recorded by the backend for a user. */ const handler = withRole("admin", async (req, res, token) => { - const { user } = req.query; + const { cursor, direction, user } = req.query; + const oasstApiClient = await createApiClient(token); - const messages: Message[] = await oasstApiClient.fetch_user_messages(user as string); - res.status(200).json(messages); + + const response = await oasstApiClient.fetch_user_messages_cursor(user as string, { + include_deleted: true, + direction: direction as "back", + cursor: cursor as string, + max_count: LIMIT, + desc: true, + }); + + res.status(200).json(response); }); export default handler; diff --git a/website/src/pages/messages/index.tsx b/website/src/pages/messages/index.tsx index 4cae792a..6c1d6f7e 100644 --- a/website/src/pages/messages/index.tsx +++ b/website/src/pages/messages/index.tsx @@ -3,7 +3,7 @@ import Head from "next/head"; import { useTranslation } from "next-i18next"; import { useCookies } from "react-cookie"; import { getDashboardLayout } from "src/components/Layout"; -import { MessageTable } from "src/components/Messages/MessageTable"; +import { MessageConversation } from "src/components/Messages/MessageConversation"; import { get } from "src/lib/api"; import useSWRImmutable from "swr/immutable"; export { getDefaultStaticProps as getStaticProps } from "src/lib/default_static_props"; @@ -38,7 +38,7 @@ const MessagesDashboard = () => { borderRadius="xl" className="p-3 sm:p-4 shadow-sm" > - {messages ? : } + {messages ? : }
@@ -52,7 +52,11 @@ const MessagesDashboard = () => { borderRadius="xl" className="p-6 shadow-sm" > - {userMessages ? : } + {userMessages ? ( + + ) : ( + + )} diff --git a/website/src/styles/Theme/components/Table.ts b/website/src/styles/Theme/components/Table.ts new file mode 100644 index 00000000..ebf9f9df --- /dev/null +++ b/website/src/styles/Theme/components/Table.ts @@ -0,0 +1,20 @@ +import { tableAnatomy } from "@chakra-ui/anatomy"; +import { createMultiStyleConfigHelpers } from "@chakra-ui/react"; + +const { definePartsStyle, defineMultiStyleConfig } = createMultiStyleConfigHelpers(tableAnatomy.keys); + +export const tableTheme = defineMultiStyleConfig({ + variants: { + simple: definePartsStyle(({ colorMode }) => { + const isLightMode = colorMode === "light"; + return { + td: { + borderColor: isLightMode ? "gray.100" : "gray.800", + }, + th: { + borderColor: isLightMode ? "gray.100" : "gray.800", + }, + }; + }), + }, +}); diff --git a/website/src/styles/Theme/index.ts b/website/src/styles/Theme/index.ts index 91d54088..2fde5a8c 100644 --- a/website/src/styles/Theme/index.ts +++ b/website/src/styles/Theme/index.ts @@ -5,6 +5,7 @@ import { colors } from "./colors"; import { badgeTheme } from "./components/Badge"; import { cardTheme } from "./components/Card"; import { containerTheme } from "./components/Container"; +import { tableTheme } from "./components/Table"; const config: ThemeConfig = { initialColorMode: "light", @@ -16,6 +17,7 @@ const components = { Badge: badgeTheme, Container: containerTheme, Card: cardTheme, + Table: tableTheme, }; const breakpoints = { diff --git a/website/src/types/Conversation.ts b/website/src/types/Conversation.ts index 89713107..57a9efbb 100644 --- a/website/src/types/Conversation.ts +++ b/website/src/types/Conversation.ts @@ -32,3 +32,11 @@ export interface Message extends MessageEmojis { export interface Conversation { messages: Message[]; } + +export type FetchUserMessagesCursorResponse = { + next?: string; + prev?: string; + sort_key: string; + items: Message[]; + order: "asc" | "desc"; +}; diff --git a/website/src/types/Users.ts b/website/src/types/Users.ts index 5100dec4..6dd65e28 100644 --- a/website/src/types/Users.ts +++ b/website/src/types/Users.ts @@ -75,11 +75,11 @@ export interface BackendUser extends BackendUserCore { /** * An expanded User for the web. */ -export interface User extends BackendUser { +export interface User extends BackendUser { /** * The user's roles within the webapp. */ - role: string; + role: TRole; } export type FetchUsersParams = { diff --git a/website/src/types/utils.ts b/website/src/types/utils.ts index 82c35036..f3ac0af3 100644 --- a/website/src/types/utils.ts +++ b/website/src/types/utils.ts @@ -1,3 +1,10 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ // https://github.com/ts-essentials/ts-essentials/blob/25cae45c162f8784e3cdae8f43783d0c66370a57/lib/types.ts#L437 // eslint-disable-next-line @typescript-eslint/no-explicit-any export type ElementOf = T extends readonly (infer ET)[] ? ET : never; +type AnyRecord = Record; +type KeyofBase = keyof any; + +export type AnyArray = Array | ReadonlyArray; + +export type StrictOmit = T extends AnyArray ? never : Omit; From ebd05e8d32c2d3ae399a06c4f1fbe19027bb152c Mon Sep 17 00:00:00 2001 From: Keith Stevens Date: Fri, 10 Feb 2023 15:47:43 +0900 Subject: [PATCH 32/54] Fixing basque language name hydration issues on Google Chrome (#1415) --- .../LanguageSelector/LanguageSelector.tsx | 7 ++----- website/src/components/Messages/LabelFlagGroup.tsx | 3 ++- website/src/components/Survey/TrackedTextarea.tsx | 5 +++-- website/src/lib/languages.ts | 13 +++++++++++++ website/src/pages/messages/index.tsx | 3 ++- 5 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 website/src/lib/languages.ts diff --git a/website/src/components/LanguageSelector/LanguageSelector.tsx b/website/src/components/LanguageSelector/LanguageSelector.tsx index 4ed9ede9..06a4096b 100644 --- a/website/src/components/LanguageSelector/LanguageSelector.tsx +++ b/website/src/components/LanguageSelector/LanguageSelector.tsx @@ -3,6 +3,7 @@ import { useRouter } from "next/router"; import { useTranslation } from "next-i18next"; import { useCallback, useEffect, useMemo } from "react"; import { useCookies } from "react-cookie"; +import { getLocaleDisplayName } from "src/lib/languages"; const LanguageSelector = () => { const router = useRouter(); @@ -20,15 +21,11 @@ const LanguageSelector = () => { } }, [cookies, setCookie, router]); - const firstLetterUppercase = (str) => { - return str.charAt(0).toLocaleUpperCase() + str.slice(1); - }; - // Memo the set of locales and their display names. const localesAndNames = useMemo(() => { return router.locales.map((locale) => ({ locale, - name: firstLetterUppercase(new Intl.DisplayNames([locale], { type: "language" }).of(locale)), + name: getLocaleDisplayName(locale), })); }, [router.locales]); diff --git a/website/src/components/Messages/LabelFlagGroup.tsx b/website/src/components/Messages/LabelFlagGroup.tsx index 7e135d24..7598627e 100644 --- a/website/src/components/Messages/LabelFlagGroup.tsx +++ b/website/src/components/Messages/LabelFlagGroup.tsx @@ -2,6 +2,7 @@ import { Button, Flex, Tooltip } from "@chakra-ui/react"; import { useTranslation } from "next-i18next"; import { useCookies } from "react-cookie"; import { getTypeSafei18nKey } from "src/lib/i18n"; +import { getLocaleDisplayName } from "src/lib/languages"; interface LabelFlagGroupProps { values: number[]; @@ -21,7 +22,7 @@ export const LabelFlagGroup = ({ const { t } = useTranslation("labelling"); const [cookies] = useCookies(["NEXT_LOCALE"]); const currentLanguage = cookies["NEXT_LOCALE"]; - const expectedLanguageName = new Intl.DisplayNames(currentLanguage, { type: "language" }).of(expectedLanguage); + const expectedLanguageName = getLocaleDisplayName(expectedLanguage, currentLanguage); return ( {labelNames.map((name, idx) => ( diff --git a/website/src/components/Survey/TrackedTextarea.tsx b/website/src/components/Survey/TrackedTextarea.tsx index bc86a864..1b06d6e8 100644 --- a/website/src/components/Survey/TrackedTextarea.tsx +++ b/website/src/components/Survey/TrackedTextarea.tsx @@ -5,6 +5,7 @@ import { useTranslation } from "next-i18next"; import React from "react"; import { useCookies } from "react-cookie"; import { LanguageAbbreviations } from "src/lib/iso6393"; +import { getLocaleDisplayName } from "src/lib/languages"; import { colors } from "src/styles/Theme/colors"; interface TrackedTextboxProps { @@ -80,8 +81,8 @@ export const TrackedTextarea = (props: TrackedTextboxProps) => { > {detectedLang} diff --git a/website/src/lib/languages.ts b/website/src/lib/languages.ts new file mode 100644 index 00000000..3283be73 --- /dev/null +++ b/website/src/lib/languages.ts @@ -0,0 +1,13 @@ +/** + * Returns the locale's name. + */ +export const getLocaleDisplayName = (locale, displayLocale = undefined) => { + // Different browsers seem to handle "eu" differently from the Node server. + // Special case this to avoid a hydration failure. + if (locale === "eu") { + return "Eurakasa"; + } + const displayName = new Intl.DisplayNames([displayLocale || locale], { type: "language" }).of(locale); + // Return the Titlecased version of the language name. + return displayName.charAt(0).toLocaleUpperCase() + displayName.slice(1); +}; diff --git a/website/src/pages/messages/index.tsx b/website/src/pages/messages/index.tsx index 6c1d6f7e..92784bb1 100644 --- a/website/src/pages/messages/index.tsx +++ b/website/src/pages/messages/index.tsx @@ -7,6 +7,7 @@ import { MessageConversation } from "src/components/Messages/MessageConversation import { get } from "src/lib/api"; import useSWRImmutable from "swr/immutable"; export { getDefaultStaticProps as getStaticProps } from "src/lib/default_static_props"; +import { getLocaleDisplayName } from "src/lib/languages"; const MessagesDashboard = () => { const { t } = useTranslation(["message"]); @@ -28,7 +29,7 @@ const MessagesDashboard = () => { {t("recent_messages", { - language: new Intl.DisplayNames([currentLanguage], { type: "language" }).of(currentLanguage), + language: getLocaleDisplayName(currentLanguage), })} Date: Fri, 10 Feb 2023 07:49:11 +0100 Subject: [PATCH 33/54] increase shared-mem setting of backend postgres container to 512mb --- docker-compose.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yaml b/docker-compose.yaml index 3cfb4c21..1f1d10d5 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -21,6 +21,7 @@ services: image: ghcr.io/laion-ai/open-assistant/oasst-postgres pull_policy: always restart: always + shm_size: 512mb ports: - 5432:5432 environment: From dfeb9698844c36276e9bfe4ad9b41b641fdf647f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=B6pf?= Date: Fri, 10 Feb 2023 08:27:32 +0100 Subject: [PATCH 34/54] move shm_size setting to playbook --- ansible/deploy-to-node.yaml | 1 + docker-compose.yaml | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/ansible/deploy-to-node.yaml b/ansible/deploy-to-node.yaml index 2111e1fc..93e8756f 100644 --- a/ansible/deploy-to-node.yaml +++ b/ansible/deploy-to-node.yaml @@ -82,6 +82,7 @@ interval: 2s timeout: 2s retries: 10 + shm_size: 1G loop: - name: backend - name: web diff --git a/docker-compose.yaml b/docker-compose.yaml index 1f1d10d5..3cfb4c21 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -21,7 +21,6 @@ services: image: ghcr.io/laion-ai/open-assistant/oasst-postgres pull_policy: always restart: always - shm_size: 512mb ports: - 5432:5432 environment: From 6dc884864b498a549b6edb25ac9bf7d34953b924 Mon Sep 17 00:00:00 2001 From: Shahul ES Date: Fri, 10 Feb 2023 13:38:19 +0530 Subject: [PATCH 35/54] Cornell movies dialog dataset (#1319) * cornell movie dialogs --- .../data-augmentation/movie-dialogs/README.md | 42 ++ .../convert-to-instruction-format.ipynb | 649 ++++++++++++++++++ 2 files changed, 691 insertions(+) create mode 100644 notebooks/data-augmentation/movie-dialogs/README.md create mode 100644 notebooks/data-augmentation/movie-dialogs/convert-to-instruction-format.ipynb diff --git a/notebooks/data-augmentation/movie-dialogs/README.md b/notebooks/data-augmentation/movie-dialogs/README.md new file mode 100644 index 00000000..9f128b6e --- /dev/null +++ b/notebooks/data-augmentation/movie-dialogs/README.md @@ -0,0 +1,42 @@ +## Dataset Summary + +The dataset was created using +[Cornell Movies Dialog Corpus](https://www.cs.cornell.edu/~cristian/Cornell_Movie-Dialogs_Corpus.html) +which contains a large metadata-rich collection of fictional conversations +extracted from raw movie scripts. Dialogs and meta-data from the underlying +Corpus were used to design a dataset that can be used to InstructGPT based +models to learn movie scripts. + +Example : + +``` +User: Assume RICK and ALICE are characters from a fantasy-horror movie, continue the conversation between them + RICK: I heard you screaming. Was it a bad one? + ALICE: It was bad. + RICK: Doesn't the dream master work for you anymore? +Assistant: Sure + ALICE: I can't find him. + RICK: Hey, since when do you play Thomas Edison? This looks like Sheila's. + ALICE: It is...was. It's a zapper, it might help me stay awake. + RICK: Yeah, or turn you into toast. +``` + +## Usage + +```python + +from datasets import load_dataset +dataset = load_dataset("shahules786/OA-cornell-movies-dialog") +``` + +## Citations + +``` +@InProceedings{Danescu-Niculescu-Mizil+Lee:11a, + author={Cristian Danescu-Niculescu-Mizil and Lillian Lee}, + title={Chameleons in imagined conversations: + A new approach to understanding coordination of linguistic style in dialogs.}, + booktitle={Proceedings of the Workshop on Cognitive Modeling and Computational Linguistics, ACL 2011}, + year={2011} +} +``` diff --git a/notebooks/data-augmentation/movie-dialogs/convert-to-instruction-format.ipynb b/notebooks/data-augmentation/movie-dialogs/convert-to-instruction-format.ipynb new file mode 100644 index 00000000..9d82bdaf --- /dev/null +++ b/notebooks/data-augmentation/movie-dialogs/convert-to-instruction-format.ipynb @@ -0,0 +1,649 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "ec8d6189", + "metadata": {}, + "source": [ + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LAION-AI/Open-Assistant/blob/main/notebooks/data-augmentation/movie-dialogs/convert-to-instruction-format.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "493f2529", + "metadata": {}, + "source": [ + "## Imports" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "65a47f83", + "metadata": {}, + "outputs": [], + "source": [ + "from datasets import load_dataset\n", + "import numpy as np\n", + "import json\n", + "from tqdm import tqdm\n", + "\n", + "IMDB = 7.0" + ] + }, + { + "cell_type": "markdown", + "id": "480440f6", + "metadata": {}, + "source": [ + "## Dialog templates\n", + "Templates for converting dialogs to prompts" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "fcfedd7f", + "metadata": {}, + "outputs": [], + "source": [ + "DIALOG_TEMPLATES = {\n", + " ### template for 4+ line dialogs\n", + " \"four_more_lines\": [\n", + " \"\"\"\n", + "Here's a {template} between {char1} and {char2} in a scene from a {genre} movie\n", + " {dialogue1}\n", + "User : Can you continue the {template}\n", + "Assistant : Sure, the next dialogue for this scene could be\n", + " {dialogue2}\n", + " \"\"\",\n", + " \"\"\"\n", + " {dialogue1}\n", + "User : Can you provide more dialog assuming {genre} movie\n", + " {dialogue2}\n", + "\"\"\",\n", + " \"\"\"\n", + "I'm trying to complete the dialog for my characters {char1} and {char2}. Here's the {template}, Please help me complete it\n", + " {dialogue1}\n", + "Assistant : Sure\n", + " {dialogue2}\n", + "\"\"\",\n", + " \"\"\"\n", + "User : Assume {char1} and {char2} are characters from a {genre} movie, continue the conversation between them\n", + " {dialogue1}\n", + "Assistant : Sure\n", + " {dialogue2}\n", + "\"\"\",\n", + " ],\n", + " ## template for 4 line dialogs\n", + " \"four_lines\": [\n", + " \"\"\"\n", + " {dialogue1}\n", + "User : provide a response assuming you're {char2}\n", + "Assistant : Sure\n", + " {dialogue2}\n", + "\"\"\",\n", + " \"\"\"\n", + " {dialogue1}\n", + "User : respond as {char2} to complete the conversation\n", + "Assistant : Sure\n", + " {dialogue2}\n", + "\"\"\",\n", + " ],\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "2047056e", + "metadata": {}, + "source": [ + "- Download Cornell-movies dialog dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "e413a053", + "metadata": {}, + "outputs": [], + "source": [ + "! wget wget https://zissou.infosci.cornell.edu/convokit/datasets/movie-corpus/movie-corpus.zip\n", + "! unzip movie-corpus.zip -d ./Data/" + ] + }, + { + "cell_type": "markdown", + "id": "5e2aab0d", + "metadata": {}, + "source": [ + "## Code" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "25cae04e", + "metadata": {}, + "outputs": [], + "source": [ + "def get_movie_dialogs():\n", + "\n", + " with open(\"./Data/movie-corpus/utterances.jsonl\", \"r\") as json_file:\n", + " conversations = list(json_file)\n", + " speakers = json.load(open(\"./Data/movie-corpus/speakers.json\"))\n", + " movie_dialog_dict = {}\n", + " for dialog in tqdm(conversations):\n", + " dialog = eval(dialog.replace(\"null\", \"None\"))\n", + " movie_dialog_dict[dialog[\"id\"]] = {\n", + " \"characterName\": speakers[dialog[\"speaker\"]][\"meta\"][\"character_name\"],\n", + " \"text\": dialog[\"text\"],\n", + " \"characterID\": dialog[\"speaker\"],\n", + " }\n", + "\n", + " return movie_dialog_dict" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "3b949bc7", + "metadata": {}, + "outputs": [], + "source": [ + "def get_dialogs(dialog_dict, start, end):\n", + "\n", + " dialog_list = []\n", + " for idx in range(start, end + 1):\n", + " dialog_list.append(dialog_dict[f\"L{idx}\"][\"characterName\"] + \": \" + dialog_dict[f\"L{idx}\"][\"text\"])\n", + " num_lines = len(dialog_list)\n", + "\n", + " assert num_lines >= 1, \"Number of lines should be greater than one\"\n", + "\n", + " if num_lines < 6:\n", + " dialog1 = \"\\n \".join(dialog_list[:-1])\n", + " dialog2 = dialog_list[-1]\n", + " else:\n", + " dialog_len = np.random.randint(3, (num_lines // 2) + 1)\n", + " dialog1 = \"\\n \".join(dialog_list[:dialog_len])\n", + " dialog2 = \"\\n \".join(dialog_list[dialog_len:])\n", + "\n", + " return dialog1, dialog2\n", + "\n", + "\n", + "def choose_prompt(num_lines):\n", + "\n", + " assert num_lines >= 1, \"Number of lines should be greater than one\"\n", + "\n", + " if num_lines < 6:\n", + " prompt = np.random.choice(DIALOG_TEMPLATES[\"four_lines\"])\n", + "\n", + " else:\n", + " prompt = np.random.choice(DIALOG_TEMPLATES[\"four_more_lines\"])\n", + "\n", + " return prompt\n", + "\n", + "\n", + "def convert_to_prompts(dataset, movie_dialog_dict, output_dir=\".\", split=\"train\"):\n", + "\n", + " with open(f\"{output_dir}/{split}.jsonl\", \"w\", encoding=\"utf8\") as output:\n", + "\n", + " i = 0\n", + " while i < len(dataset[\"train\"]):\n", + "\n", + " data = dataset[split][i]\n", + " if float(data[\"movieIMDBRating\"].strip()) >= IMDB:\n", + " max_lines = np.random.randint(7, 12)\n", + " lineids = [int(lineid[1:]) for lineid in data[\"utterance\"][\"LineID\"]]\n", + " num_lines = len(lineids)\n", + " char_ids = sorted([data[\"characterID1\"].strip(), data[\"characterID1\"].strip()])\n", + " while num_lines < max_lines:\n", + " i += 1\n", + " data = dataset[split][i]\n", + " char_id_new = sorted([data[\"characterID1\"].strip(), data[\"characterID1\"].strip()])\n", + " ## make sure that characters are the same\n", + " if char_id_new == char_ids:\n", + " lineids_new = [int(lineid[1:]) for lineid in data[\"utterance\"][\"LineID\"]]\n", + " if lineids_new[0] == (lineids[-1] + 1): ##ensure continuety\n", + " lineids.extend(lineids_new)\n", + " else:\n", + " break\n", + " else:\n", + " break\n", + " num_lines = len(lineids)\n", + "\n", + " genre = \"-\".join(data[\"movieGenres\"][:2])\n", + " template = np.random.choice([\"dialog\", \"script\", \"play\"])\n", + " char1 = movie_dialog_dict[f\"L{lineids[0]}\"][\"characterName\"]\n", + "\n", + " if num_lines < 6:\n", + " if num_lines % 2 == 0:\n", + " char2 = movie_dialog_dict[f\"L{lineids[1]}\"][\"characterName\"]\n", + " else:\n", + " char2 = char1\n", + " else:\n", + " char2 = movie_dialog_dict[f\"L{lineids[1]}\"][\"characterName\"]\n", + "\n", + " dialogue1, dialogue2 = get_dialogs(movie_dialog_dict, lineids[0], lineids[-1])\n", + " prompt = choose_prompt(num_lines)\n", + "\n", + " prompt = prompt.format(\n", + " char1=char1, char2=char2, dialogue1=dialogue1, dialogue2=dialogue2, genre=genre, template=template\n", + " )\n", + " output.write(f\"{json.dumps({'conversation': prompt})}\\n\")\n", + " i += 1" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "3ff310fd", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|███████████████████████████████| 304713/304713 [00:54<00:00, 5628.12it/s]\n", + "Found cached dataset cornell_movie_dialog (/home/shahul/.cache/huggingface/datasets/cornell_movie_dialog/default/0.1.0/b67b3433cf894b551cddcd82efdff0826f39b39a11d5c149e746a546a8dc85f3)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "6fee977c69a3403ebe77c4669fcb25d7", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/1 [00:00 Date: Fri, 10 Feb 2023 09:11:15 +0100 Subject: [PATCH 36/54] add env for mods --- .github/workflows/deploy-to-node.yaml | 1 + ansible/deploy-to-node.yaml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.github/workflows/deploy-to-node.yaml b/.github/workflows/deploy-to-node.yaml index 522a7da7..af695bdd 100644 --- a/.github/workflows/deploy-to-node.yaml +++ b/.github/workflows/deploy-to-node.yaml @@ -26,6 +26,7 @@ jobs: environment: ${{ inputs.stack-name }} env: WEB_ADMIN_USERS: ${{ secrets.DEV_WEB_ADMIN_USERS }} + WEB_MODERATOR_USERS: ${{ secrets.DEV_WEB_MODERATOR_USERS }} WEB_DISCORD_CLIENT_ID: ${{ secrets.DEV_WEB_DISCORD_CLIENT_ID }} WEB_DISCORD_CLIENT_SECRET: ${{ secrets.DEV_WEB_DISCORD_CLIENT_SECRET }} WEB_EMAIL_SERVER_HOST: ${{ secrets.DEV_WEB_EMAIL_SERVER_HOST }} diff --git a/ansible/deploy-to-node.yaml b/ansible/deploy-to-node.yaml index 93e8756f..3cb15a62 100644 --- a/ansible/deploy-to-node.yaml +++ b/ansible/deploy-to-node.yaml @@ -170,6 +170,8 @@ network_mode: "oasst-{{ stack_name }}" env: ADMIN_USERS: "{{ lookup('ansible.builtin.env', 'WEB_ADMIN_USERS') }}" + MODERATOR_USERS: + "{{ lookup('ansible.builtin.env', 'WEB_MODERATOR_USERS') }}" DATABASE_URL: "postgres://postgres:{{ postgres_password }}@oasst-{{ stack_name }}-postgres-web/postgres" From 7a0bfa2d68b720ec6593a659b6851c0786afece3 Mon Sep 17 00:00:00 2001 From: notmd <33456881+notmd@users.noreply.github.com> Date: Fri, 10 Feb 2023 16:18:48 +0700 Subject: [PATCH 37/54] add moderator role (#1419) --- website/.env | 1 + website/src/components/AdminArea.tsx | 5 +++- website/src/components/Header/UserMenu.tsx | 15 +++++++++--- .../LeaderboardTable/LeaderboardTable.tsx | 10 ++++---- .../Messages/MessageEmojiButton.tsx | 6 ++--- .../components/Messages/MessageTableEntry.tsx | 6 ++--- website/src/components/RoleSelect.tsx | 2 +- website/src/hooks/auth/useHasAnyRole.ts | 8 +++++++ website/src/lib/auth.ts | 14 +++++++++++ .../pages/api/admin/delete_message/[id].ts | 4 ++-- website/src/pages/api/admin/parameters.ts | 10 ++++++-- website/src/pages/api/admin/status.ts | 4 ++-- website/src/pages/api/admin/stop_tree/[id].ts | 4 ++-- website/src/pages/api/admin/trollboard.ts | 4 ++-- website/src/pages/api/admin/user_messages.ts | 4 ++-- website/src/pages/api/admin/users.ts | 4 ++-- website/src/pages/api/auth/[...nextauth].ts | 24 +++++++++++++++++-- website/types/env.d.ts | 2 ++ 18 files changed, 95 insertions(+), 32 deletions(-) create mode 100644 website/src/hooks/auth/useHasAnyRole.ts diff --git a/website/.env b/website/.env index 50ecb498..6c95c9a5 100644 --- a/website/.env +++ b/website/.env @@ -1,4 +1,5 @@ ADMIN_USERS = "credentials:admin,discord:root,email:admin@example.com" +MODERATOR_USERS = "credentials:mod,discord:mod,email:mod@example.com" # The database created by running the jobs in /scripts/frontend-development/docker-compose.yaml DATABASE_URL=postgres://postgres:postgres@localhost:5433/oasst_web diff --git a/website/src/components/AdminArea.tsx b/website/src/components/AdminArea.tsx index 8e6d1229..6bc7a919 100644 --- a/website/src/components/AdminArea.tsx +++ b/website/src/components/AdminArea.tsx @@ -10,9 +10,12 @@ export const AdminArea = ({ children }: { children: ReactNode }) => { if (status === "loading") { return; } - if (session?.user.role === "admin") { + const role = session?.user.role; + + if (role === "admin" || role === "moderator") { return; } + router.push("/"); }, [router, session, status]); return
{status === "loading" ? "loading..." : children}
; diff --git a/website/src/components/Header/UserMenu.tsx b/website/src/components/Header/UserMenu.tsx index cad2dbe8..aba03f05 100644 --- a/website/src/components/Header/UserMenu.tsx +++ b/website/src/components/Header/UserMenu.tsx @@ -1,5 +1,6 @@ import { Avatar, + Badge, Box, Link, Menu, @@ -16,6 +17,7 @@ import NextLink from "next/link"; import { signOut, useSession } from "next-auth/react"; import { useTranslation } from "next-i18next"; import React, { ElementType, useCallback } from "react"; +import { useHasAnyRole } from "src/hooks/auth/useHasAnyRole"; interface MenuOption { name: string; @@ -31,7 +33,7 @@ export function UserMenu() { signOut({ callbackUrl: "/" }); }, []); const { data: session, status } = useSession(); - + const isAdminOrMod = useHasAnyRole(["admin", "moderator"]); if (!session || status !== "authenticated") { return null; } @@ -56,7 +58,7 @@ export function UserMenu() { }, ]; - if (session.user.role === "admin") { + if (isAdminOrMod) { options.unshift({ name: t("admin_dashboard"), href: "/admin", @@ -77,7 +79,14 @@ export function UserMenu() {
- {session.user.name} + + {session.user.name} + {isAdminOrMod ? ( + + {session.user.role} + + ) : null} + {/* 3,200 */} diff --git a/website/src/components/LeaderboardTable/LeaderboardTable.tsx b/website/src/components/LeaderboardTable/LeaderboardTable.tsx index fc3ae099..95cbd376 100644 --- a/website/src/components/LeaderboardTable/LeaderboardTable.tsx +++ b/website/src/components/LeaderboardTable/LeaderboardTable.tsx @@ -4,7 +4,7 @@ import { MoreHorizontal } from "lucide-react"; import NextLink from "next/link"; import { useTranslation } from "next-i18next"; import React, { useMemo } from "react"; -import { useHasRole } from "src/hooks/auth/useHasRole"; +import { useHasAnyRole } from "src/hooks/auth/useHasAnyRole"; import { LeaderboardEntity, LeaderboardReply, LeaderboardTimeFrame } from "src/types/Leaderboard"; import { DataTable, DataTableColumnDef } from "../DataTable/DataTable"; @@ -41,7 +41,7 @@ export const LeaderboardTable = ({ `/api/leaderboard?time_frame=${timeFrame}&limit=${limit}&includeUserStats=${!hideCurrentUserRanking}` ); - const isAdmin = useHasRole("admin"); + const isAdminOrMod = useHasAnyRole(["admin", "moderator"]); const columns: DataTableColumnDef[] = useMemo( () => [ @@ -51,7 +51,7 @@ export const LeaderboardTable = ({ cell: (ctx) => ctx.row.original.isSpaceRow ? ( - ) : isAdmin ? ( + ) : isAdminOrMod ? ( jsonExpandRowModel.renderCell(ctx) ) : ( ctx.getValue() @@ -62,7 +62,7 @@ export const LeaderboardTable = ({ columnHelper.accessor("display_name", { header: t("user"), cell: ({ getValue, row }) => - isAdmin ? ( + isAdminOrMod ? ( {getValue()} @@ -83,7 +83,7 @@ export const LeaderboardTable = ({ header: t("label"), }), ], - [isAdmin, t] + [isAdminOrMod, t] ); const { diff --git a/website/src/components/Messages/MessageEmojiButton.tsx b/website/src/components/Messages/MessageEmojiButton.tsx index e2cfd569..2c0c2442 100644 --- a/website/src/components/Messages/MessageEmojiButton.tsx +++ b/website/src/components/Messages/MessageEmojiButton.tsx @@ -1,5 +1,5 @@ import { Button, ButtonProps } from "@chakra-ui/react"; -import { useHasRole } from "src/hooks/auth/useHasRole"; +import { useHasAnyRole } from "src/hooks/auth/useHasAnyRole"; import { MessageEmoji } from "src/types/Conversation"; import { emojiIcons } from "src/types/Emoji"; @@ -23,12 +23,12 @@ export const MessageEmojiButton = ({ sx, }: MessageEmojiButtonProps) => { const EmojiIcon = emojiIcons.get(emoji.name); - const isAdmin = useHasRole("admin"); + const isAdminOrMod = useHasAnyRole(["admin", "moderator"]); if (!EmojiIcon) return null; const isDisabled = !!(userIsAuthor ? true : disabled); - const showCount = (emoji.count > 0 && userReacted) || userIsAuthor || isAdmin; + const showCount = (emoji.count > 0 && userReacted) || userIsAuthor || isAdminOrMod; return (