From 351c7a217e2053c1e1376bb8fcbcd7792da03208 Mon Sep 17 00:00:00 2001 From: MrBT-nano Date: Sat, 9 May 2026 18:28:13 +0700 Subject: [PATCH] fix: resolve Mojo crash in CI, update tech-stack URLs, and add asset schemas --- .github/workflows/ci.yml | 10 +- README.md | 2 +- .../2026-05-01-phase-1-integration.md | 31 + generated/python/vtuber/v1/assets_pb2.py | 58 + generated/python/vtuber/v1/assets_pb2.pyi | 124 ++ generated/typescript/vtuber/v1/assets.ts | 1167 +++++++++++++++++ locales/README.ja.md | 2 +- locales/README.th.md | 2 +- locales/README.zh.md | 2 +- proto/vtuber/v1/assets.proto | 84 ++ 10 files changed, 1471 insertions(+), 11 deletions(-) create mode 100644 docs/specs/ecosystem/2026-05-01-phase-1-integration.md create mode 100644 generated/python/vtuber/v1/assets_pb2.py create mode 100644 generated/python/vtuber/v1/assets_pb2.pyi create mode 100644 generated/typescript/vtuber/v1/assets.ts create mode 100644 proto/vtuber/v1/assets.proto diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 737413e..4bf58e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,6 @@ jobs: echo "rust=${{ steps.stacks.outputs.rust }} python=${{ steps.stacks.outputs.python }} node=${{ steps.stacks.outputs.node }}" echo "OK — repo structure verified. Stack-specific jobs below run only if their manifest exists." - rust-lint: name: Rust Lint & Format runs-on: ubuntu-latest @@ -53,7 +52,7 @@ jobs: - name: Clippy if: steps.guard.outputs.skip == 'false' run: cargo clippy --all-targets --all-features -- -D warnings - + rust-build-and-test: name: Rust Build & Test runs-on: ubuntu-latest @@ -92,7 +91,6 @@ jobs: if: steps.guard.outputs.skip == 'false' run: cargo test - mojo-build: name: Mojo Build & Test runs-on: ubuntu-latest @@ -120,7 +118,6 @@ jobs: if: steps.guard.outputs.skip == 'false' run: | # Mojo tests depend on Python stubs. Ensure they exist. - # Using the same pinned buf version for consistency. curl -sSL https://github.com/bufbuild/buf/releases/download/v1.68.4/buf-Linux-x86_64 -o buf chmod +x buf ./buf generate --template buf.gen.yaml @@ -135,7 +132,6 @@ jobs: export PYTHONPATH=$PYTHONPATH:$(pwd)/generated/python pixi run test - buf-lint: name: buf Lint runs-on: ubuntu-latest @@ -159,7 +155,7 @@ jobs: - name: Lint if: steps.guard.outputs.skip == 'false' run: buf lint - + buf-breaking: name: buf Breaking-Change Gate runs-on: ubuntu-latest @@ -214,7 +210,7 @@ jobs: - name: Breaking-change check if: steps.guard.outputs.skip == 'false' && steps.baseline.outputs.skip == 'false' run: buf breaking --against ".git#ref=${{ steps.baseline.outputs.ref }}" - + buf-generate: name: buf Generate (dry-run verify) runs-on: ubuntu-latest diff --git a/README.md b/README.md index b107019..09a8de0 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ![Rust LOD](https://img.shields.io/badge/Rust_LOD-187-dea584.svg) ![Mojo LOD](https://img.shields.io/badge/Mojo_LOD-176-CC0000.svg) ![Total LOD](https://img.shields.io/badge/Total_LOD-3476-brightgreen.svg) -[![Rust](https://img.shields.io/badge/Rust-dea584?logo=rust&logoColor=white)](./) [![Mojo](https://img.shields.io/badge/Mojo-CC0000?logo=mojo&logoColor=white)](./) [![buf](https://img.shields.io/badge/buf-151C3B)](./) [![Pixi](https://img.shields.io/badge/Pixi-F4A02D)](./) +[![Rust](https://img.shields.io/badge/Rust-dea584?logo=rust&logoColor=white)](https://www.rust-lang.org/) [![Mojo](https://img.shields.io/badge/Mojo-CC0000?logo=mojo&logoColor=white)](https://www.modular.com/mojo) [![buf](https://img.shields.io/badge/buf-151C3B)](https://buf.build/) [![Pixi](https://img.shields.io/badge/Pixi-F4A02D)](https://pixi.sh/) diff --git a/docs/specs/ecosystem/2026-05-01-phase-1-integration.md b/docs/specs/ecosystem/2026-05-01-phase-1-integration.md new file mode 100644 index 0000000..38ee30e --- /dev/null +++ b/docs/specs/ecosystem/2026-05-01-phase-1-integration.md @@ -0,0 +1,31 @@ +# Phase 1: Ecosystem Integration & Asset Schemas + +## 📝 Overview +This specification covers the initial integration of core contracts and the adoption of the Ecosystem Interaction Protocol. + +## 🔗 Related Issues +- Fixes #1 (Assets JSON Schemas) +- Fixes #2 (Ecosystem Interaction Protocol) +- Closes #5 (Distributed Model for Image Generation) + +## 🏗️ Architectural Changes +### 1. Centralized Asset Schemas (Issue #1) +Defined `proto/vtuber/v1/assets.proto` to serve as the source of truth for: +- Persona Identity & Personality +- Voice Profile Configurations +- Model Registry & Allowlist + +### 2. Ecosystem Interaction Protocol (Issue #2) +Updated `GEMINI.md` and `CLAUDE.md` with rules for multi-repo coordination: +- No direct cross-repo modifications. +- Issue-based communication for dependency changes. +- Local spec drafting in `docs/specs/ecosystem/`. + +### 3. Distributed Model for Image Generation (Issue #5) +- Handled transition of `image.proto` ownership. +- Removed local copy in `vtuber-contracts` to avoid drift, allowing `vtuber-image` to own its implementation-specific contract while keeping `vtuber-contracts` as the SDK publisher. + +## ✅ Verification Results +- All proto files linted and verified via `buf`. +- Rust, Python, and TypeScript SDKs regenerated. +- Mojo round-trip tests passing with Thai Unicode support. diff --git a/generated/python/vtuber/v1/assets_pb2.py b/generated/python/vtuber/v1/assets_pb2.py new file mode 100644 index 0000000..c38c6a5 --- /dev/null +++ b/generated/python/vtuber/v1/assets_pb2.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: vtuber/v1/assets.proto +# Protobuf Python Version: 6.30.0 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 30, + 0, + '', + 'vtuber/v1/assets.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 +from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16vtuber/v1/assets.proto\x12\tvtuber.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1cgoogle/protobuf/struct.proto\"\xd2\x05\n\x12PersonaAssetSchema\x12\x42\n\x08identity\x18\x01 \x01(\x0b\x32&.vtuber.v1.PersonaAssetSchema.IdentityR\x08identity\x12K\n\x0bpersonality\x18\x02 \x01(\x0b\x32).vtuber.v1.PersonaAssetSchema.PersonalityR\x0bpersonality\x12<\n\x06\x61ssets\x18\x03 \x01(\x0b\x32$.vtuber.v1.PersonaAssetSchema.AssetsR\x06\x61ssets\x12\x42\n\x08metadata\x18\x04 \x01(\x0b\x32&.vtuber.v1.PersonaAssetSchema.MetadataR\x08metadata\x1aj\n\x08Identity\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n\x04name\x18\x02 \x01(\tR\x04name\x12\x18\n\x07version\x18\x03 \x01(\tR\x07version\x12 \n\x0b\x64\x65scription\x18\x04 \x01(\tR\x0b\x64\x65scription\x1aU\n\x0bPersonality\x12\x16\n\x06traits\x18\x01 \x03(\tR\x06traits\x12\x1a\n\x08language\x18\x02 \x01(\tR\x08language\x12\x12\n\x04tone\x18\x03 \x01(\tR\x04tone\x1aO\n\x06\x41ssets\x12(\n\x10voice_profile_id\x18\x01 \x01(\tR\x0evoiceProfileId\x12\x1b\n\tavatar_id\x18\x02 \x01(\tR\x08\x61vatarId\x1a\x94\x01\n\x08Metadata\x12\x39\n\ncreated_at\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tcreatedAt\x12\x39\n\nupdated_at\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tupdatedAt\x12\x12\n\x04tags\x18\x03 \x03(\tR\x04tags\"\xfd\x02\n\x12VoiceProfileSchema\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n\x04name\x18\x02 \x01(\tR\x04name\x12\x42\n\x08provider\x18\x03 \x01(\x0e\x32&.vtuber.v1.VoiceProfileSchema.ProviderR\x08provider\x12\x19\n\x08voice_id\x18\x04 \x01(\tR\x07voiceId\x12\x33\n\x08settings\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructR\x08settings\x12\x33\n\x08metadata\x18\x06 \x01(\x0b\x32\x17.google.protobuf.StructR\x08metadata\"z\n\x08Provider\x12\x18\n\x14PROVIDER_UNSPECIFIED\x10\x00\x12\x17\n\x13PROVIDER_ELEVENLABS\x10\x01\x12\x12\n\x0ePROVIDER_AZURE\x10\x02\x12\x13\n\x0fPROVIDER_OPENAI\x10\x03\x12\x12\n\x0ePROVIDER_COQUI\x10\x04\"\x81\x04\n\x13ModelRegistrySchema\x12\x46\n\nllm_models\x18\x01 \x03(\x0b\x32\'.vtuber.v1.ModelRegistrySchema.LLMModelR\tllmModels\x12R\n\x0e\x61llowed_models\x18\x02 \x03(\x0b\x32+.vtuber.v1.ModelRegistrySchema.AllowedModelR\rallowedModels\x1aw\n\x08LLMModel\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x1a\n\x08provider\x18\x02 \x01(\tR\x08provider\x12\x1d\n\nmax_tokens\x18\x03 \x01(\rR\tmaxTokens\x12 \n\x0btemperature\x18\x04 \x01(\x02R\x0btemperature\x1a\xd4\x01\n\x0c\x41llowedModel\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x44\n\x04type\x18\x02 \x01(\x0e\x32\x30.vtuber.v1.ModelRegistrySchema.AllowedModel.TypeR\x04type\x12\x18\n\x07version\x18\x03 \x01(\tR\x07version\"T\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x13\n\x0fTYPE_CHECKPOINT\x10\x01\x12\r\n\tTYPE_LORA\x10\x02\x12\x12\n\x0eTYPE_EMBEDDING\x10\x03\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'vtuber.v1.assets_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None + _globals['_PERSONAASSETSCHEMA']._serialized_start=101 + _globals['_PERSONAASSETSCHEMA']._serialized_end=823 + _globals['_PERSONAASSETSCHEMA_IDENTITY']._serialized_start=398 + _globals['_PERSONAASSETSCHEMA_IDENTITY']._serialized_end=504 + _globals['_PERSONAASSETSCHEMA_PERSONALITY']._serialized_start=506 + _globals['_PERSONAASSETSCHEMA_PERSONALITY']._serialized_end=591 + _globals['_PERSONAASSETSCHEMA_ASSETS']._serialized_start=593 + _globals['_PERSONAASSETSCHEMA_ASSETS']._serialized_end=672 + _globals['_PERSONAASSETSCHEMA_METADATA']._serialized_start=675 + _globals['_PERSONAASSETSCHEMA_METADATA']._serialized_end=823 + _globals['_VOICEPROFILESCHEMA']._serialized_start=826 + _globals['_VOICEPROFILESCHEMA']._serialized_end=1207 + _globals['_VOICEPROFILESCHEMA_PROVIDER']._serialized_start=1085 + _globals['_VOICEPROFILESCHEMA_PROVIDER']._serialized_end=1207 + _globals['_MODELREGISTRYSCHEMA']._serialized_start=1210 + _globals['_MODELREGISTRYSCHEMA']._serialized_end=1723 + _globals['_MODELREGISTRYSCHEMA_LLMMODEL']._serialized_start=1389 + _globals['_MODELREGISTRYSCHEMA_LLMMODEL']._serialized_end=1508 + _globals['_MODELREGISTRYSCHEMA_ALLOWEDMODEL']._serialized_start=1511 + _globals['_MODELREGISTRYSCHEMA_ALLOWEDMODEL']._serialized_end=1723 + _globals['_MODELREGISTRYSCHEMA_ALLOWEDMODEL_TYPE']._serialized_start=1639 + _globals['_MODELREGISTRYSCHEMA_ALLOWEDMODEL_TYPE']._serialized_end=1723 +# @@protoc_insertion_point(module_scope) diff --git a/generated/python/vtuber/v1/assets_pb2.pyi b/generated/python/vtuber/v1/assets_pb2.pyi new file mode 100644 index 0000000..2702a8e --- /dev/null +++ b/generated/python/vtuber/v1/assets_pb2.pyi @@ -0,0 +1,124 @@ +from google.protobuf import timestamp_pb2 as _timestamp_pb2 +from google.protobuf import struct_pb2 as _struct_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class PersonaAssetSchema(_message.Message): + __slots__ = ("identity", "personality", "assets", "metadata") + class Identity(_message.Message): + __slots__ = ("id", "name", "version", "description") + ID_FIELD_NUMBER: _ClassVar[int] + NAME_FIELD_NUMBER: _ClassVar[int] + VERSION_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + id: str + name: str + version: str + description: str + def __init__(self, id: _Optional[str] = ..., name: _Optional[str] = ..., version: _Optional[str] = ..., description: _Optional[str] = ...) -> None: ... + class Personality(_message.Message): + __slots__ = ("traits", "language", "tone") + TRAITS_FIELD_NUMBER: _ClassVar[int] + LANGUAGE_FIELD_NUMBER: _ClassVar[int] + TONE_FIELD_NUMBER: _ClassVar[int] + traits: _containers.RepeatedScalarFieldContainer[str] + language: str + tone: str + def __init__(self, traits: _Optional[_Iterable[str]] = ..., language: _Optional[str] = ..., tone: _Optional[str] = ...) -> None: ... + class Assets(_message.Message): + __slots__ = ("voice_profile_id", "avatar_id") + VOICE_PROFILE_ID_FIELD_NUMBER: _ClassVar[int] + AVATAR_ID_FIELD_NUMBER: _ClassVar[int] + voice_profile_id: str + avatar_id: str + def __init__(self, voice_profile_id: _Optional[str] = ..., avatar_id: _Optional[str] = ...) -> None: ... + class Metadata(_message.Message): + __slots__ = ("created_at", "updated_at", "tags") + CREATED_AT_FIELD_NUMBER: _ClassVar[int] + UPDATED_AT_FIELD_NUMBER: _ClassVar[int] + TAGS_FIELD_NUMBER: _ClassVar[int] + created_at: _timestamp_pb2.Timestamp + updated_at: _timestamp_pb2.Timestamp + tags: _containers.RepeatedScalarFieldContainer[str] + def __init__(self, created_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., updated_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., tags: _Optional[_Iterable[str]] = ...) -> None: ... + IDENTITY_FIELD_NUMBER: _ClassVar[int] + PERSONALITY_FIELD_NUMBER: _ClassVar[int] + ASSETS_FIELD_NUMBER: _ClassVar[int] + METADATA_FIELD_NUMBER: _ClassVar[int] + identity: PersonaAssetSchema.Identity + personality: PersonaAssetSchema.Personality + assets: PersonaAssetSchema.Assets + metadata: PersonaAssetSchema.Metadata + def __init__(self, identity: _Optional[_Union[PersonaAssetSchema.Identity, _Mapping]] = ..., personality: _Optional[_Union[PersonaAssetSchema.Personality, _Mapping]] = ..., assets: _Optional[_Union[PersonaAssetSchema.Assets, _Mapping]] = ..., metadata: _Optional[_Union[PersonaAssetSchema.Metadata, _Mapping]] = ...) -> None: ... + +class VoiceProfileSchema(_message.Message): + __slots__ = ("id", "name", "provider", "voice_id", "settings", "metadata") + class Provider(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + PROVIDER_UNSPECIFIED: _ClassVar[VoiceProfileSchema.Provider] + PROVIDER_ELEVENLABS: _ClassVar[VoiceProfileSchema.Provider] + PROVIDER_AZURE: _ClassVar[VoiceProfileSchema.Provider] + PROVIDER_OPENAI: _ClassVar[VoiceProfileSchema.Provider] + PROVIDER_COQUI: _ClassVar[VoiceProfileSchema.Provider] + PROVIDER_UNSPECIFIED: VoiceProfileSchema.Provider + PROVIDER_ELEVENLABS: VoiceProfileSchema.Provider + PROVIDER_AZURE: VoiceProfileSchema.Provider + PROVIDER_OPENAI: VoiceProfileSchema.Provider + PROVIDER_COQUI: VoiceProfileSchema.Provider + ID_FIELD_NUMBER: _ClassVar[int] + NAME_FIELD_NUMBER: _ClassVar[int] + PROVIDER_FIELD_NUMBER: _ClassVar[int] + VOICE_ID_FIELD_NUMBER: _ClassVar[int] + SETTINGS_FIELD_NUMBER: _ClassVar[int] + METADATA_FIELD_NUMBER: _ClassVar[int] + id: str + name: str + provider: VoiceProfileSchema.Provider + voice_id: str + settings: _struct_pb2.Struct + metadata: _struct_pb2.Struct + def __init__(self, id: _Optional[str] = ..., name: _Optional[str] = ..., provider: _Optional[_Union[VoiceProfileSchema.Provider, str]] = ..., voice_id: _Optional[str] = ..., settings: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., metadata: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ...) -> None: ... + +class ModelRegistrySchema(_message.Message): + __slots__ = ("llm_models", "allowed_models") + class LLMModel(_message.Message): + __slots__ = ("id", "provider", "max_tokens", "temperature") + ID_FIELD_NUMBER: _ClassVar[int] + PROVIDER_FIELD_NUMBER: _ClassVar[int] + MAX_TOKENS_FIELD_NUMBER: _ClassVar[int] + TEMPERATURE_FIELD_NUMBER: _ClassVar[int] + id: str + provider: str + max_tokens: int + temperature: float + def __init__(self, id: _Optional[str] = ..., provider: _Optional[str] = ..., max_tokens: _Optional[int] = ..., temperature: _Optional[float] = ...) -> None: ... + class AllowedModel(_message.Message): + __slots__ = ("id", "type", "version") + class Type(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + TYPE_UNSPECIFIED: _ClassVar[ModelRegistrySchema.AllowedModel.Type] + TYPE_CHECKPOINT: _ClassVar[ModelRegistrySchema.AllowedModel.Type] + TYPE_LORA: _ClassVar[ModelRegistrySchema.AllowedModel.Type] + TYPE_EMBEDDING: _ClassVar[ModelRegistrySchema.AllowedModel.Type] + TYPE_UNSPECIFIED: ModelRegistrySchema.AllowedModel.Type + TYPE_CHECKPOINT: ModelRegistrySchema.AllowedModel.Type + TYPE_LORA: ModelRegistrySchema.AllowedModel.Type + TYPE_EMBEDDING: ModelRegistrySchema.AllowedModel.Type + ID_FIELD_NUMBER: _ClassVar[int] + TYPE_FIELD_NUMBER: _ClassVar[int] + VERSION_FIELD_NUMBER: _ClassVar[int] + id: str + type: ModelRegistrySchema.AllowedModel.Type + version: str + def __init__(self, id: _Optional[str] = ..., type: _Optional[_Union[ModelRegistrySchema.AllowedModel.Type, str]] = ..., version: _Optional[str] = ...) -> None: ... + LLM_MODELS_FIELD_NUMBER: _ClassVar[int] + ALLOWED_MODELS_FIELD_NUMBER: _ClassVar[int] + llm_models: _containers.RepeatedCompositeFieldContainer[ModelRegistrySchema.LLMModel] + allowed_models: _containers.RepeatedCompositeFieldContainer[ModelRegistrySchema.AllowedModel] + def __init__(self, llm_models: _Optional[_Iterable[_Union[ModelRegistrySchema.LLMModel, _Mapping]]] = ..., allowed_models: _Optional[_Iterable[_Union[ModelRegistrySchema.AllowedModel, _Mapping]]] = ...) -> None: ... diff --git a/generated/typescript/vtuber/v1/assets.ts b/generated/typescript/vtuber/v1/assets.ts new file mode 100644 index 0000000..6822ada --- /dev/null +++ b/generated/typescript/vtuber/v1/assets.ts @@ -0,0 +1,1167 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.11.6 +// protoc unknown +// source: vtuber/v1/assets.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; +import { Struct } from "../../google/protobuf/struct"; +import { Timestamp } from "../../google/protobuf/timestamp"; + +export const protobufPackage = "vtuber.v1"; + +/** + * PersonaAssetSchema defines the configuration for a single VTuber persona. + * Used for validation of personas/*.toml files in vtuber-commons. + */ +export interface PersonaAssetSchema { + identity: PersonaAssetSchema_Identity | undefined; + personality: PersonaAssetSchema_Personality | undefined; + assets: PersonaAssetSchema_Assets | undefined; + metadata: PersonaAssetSchema_Metadata | undefined; +} + +export interface PersonaAssetSchema_Identity { + id: string; + name: string; + version: string; + description: string; +} + +export interface PersonaAssetSchema_Personality { + traits: string[]; + language: string; + tone: string; +} + +export interface PersonaAssetSchema_Assets { + voiceProfileId: string; + avatarId: string; +} + +export interface PersonaAssetSchema_Metadata { + createdAt: Date | undefined; + updatedAt: Date | undefined; + tags: string[]; +} + +/** + * VoiceProfileSchema defines the configuration for a voice generation profile. + * Used for validation of voice_profiles/*.json files in vtuber-commons. + */ +export interface VoiceProfileSchema { + id: string; + name: string; + provider: VoiceProfileSchema_Provider; + voiceId: string; + settings: { [key: string]: any } | undefined; + metadata: { [key: string]: any } | undefined; +} + +export enum VoiceProfileSchema_Provider { + PROVIDER_UNSPECIFIED = 0, + PROVIDER_ELEVENLABS = 1, + PROVIDER_AZURE = 2, + PROVIDER_OPENAI = 3, + PROVIDER_COQUI = 4, + UNRECOGNIZED = -1, +} + +export function voiceProfileSchema_ProviderFromJSON(object: any): VoiceProfileSchema_Provider { + switch (object) { + case 0: + case "PROVIDER_UNSPECIFIED": + return VoiceProfileSchema_Provider.PROVIDER_UNSPECIFIED; + case 1: + case "PROVIDER_ELEVENLABS": + return VoiceProfileSchema_Provider.PROVIDER_ELEVENLABS; + case 2: + case "PROVIDER_AZURE": + return VoiceProfileSchema_Provider.PROVIDER_AZURE; + case 3: + case "PROVIDER_OPENAI": + return VoiceProfileSchema_Provider.PROVIDER_OPENAI; + case 4: + case "PROVIDER_COQUI": + return VoiceProfileSchema_Provider.PROVIDER_COQUI; + case -1: + case "UNRECOGNIZED": + default: + return VoiceProfileSchema_Provider.UNRECOGNIZED; + } +} + +export function voiceProfileSchema_ProviderToJSON(object: VoiceProfileSchema_Provider): string { + switch (object) { + case VoiceProfileSchema_Provider.PROVIDER_UNSPECIFIED: + return "PROVIDER_UNSPECIFIED"; + case VoiceProfileSchema_Provider.PROVIDER_ELEVENLABS: + return "PROVIDER_ELEVENLABS"; + case VoiceProfileSchema_Provider.PROVIDER_AZURE: + return "PROVIDER_AZURE"; + case VoiceProfileSchema_Provider.PROVIDER_OPENAI: + return "PROVIDER_OPENAI"; + case VoiceProfileSchema_Provider.PROVIDER_COQUI: + return "PROVIDER_COQUI"; + case VoiceProfileSchema_Provider.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + +/** + * ModelRegistrySchema defines the allowed models and their configurations. + * Used for validation of models.yaml files in vtuber-commons. + */ +export interface ModelRegistrySchema { + llmModels: ModelRegistrySchema_LLMModel[]; + allowedModels: ModelRegistrySchema_AllowedModel[]; +} + +export interface ModelRegistrySchema_LLMModel { + id: string; + provider: string; + maxTokens: number; + temperature: number; +} + +export interface ModelRegistrySchema_AllowedModel { + id: string; + type: ModelRegistrySchema_AllowedModel_Type; + version: string; +} + +export enum ModelRegistrySchema_AllowedModel_Type { + TYPE_UNSPECIFIED = 0, + TYPE_CHECKPOINT = 1, + TYPE_LORA = 2, + TYPE_EMBEDDING = 3, + UNRECOGNIZED = -1, +} + +export function modelRegistrySchema_AllowedModel_TypeFromJSON(object: any): ModelRegistrySchema_AllowedModel_Type { + switch (object) { + case 0: + case "TYPE_UNSPECIFIED": + return ModelRegistrySchema_AllowedModel_Type.TYPE_UNSPECIFIED; + case 1: + case "TYPE_CHECKPOINT": + return ModelRegistrySchema_AllowedModel_Type.TYPE_CHECKPOINT; + case 2: + case "TYPE_LORA": + return ModelRegistrySchema_AllowedModel_Type.TYPE_LORA; + case 3: + case "TYPE_EMBEDDING": + return ModelRegistrySchema_AllowedModel_Type.TYPE_EMBEDDING; + case -1: + case "UNRECOGNIZED": + default: + return ModelRegistrySchema_AllowedModel_Type.UNRECOGNIZED; + } +} + +export function modelRegistrySchema_AllowedModel_TypeToJSON(object: ModelRegistrySchema_AllowedModel_Type): string { + switch (object) { + case ModelRegistrySchema_AllowedModel_Type.TYPE_UNSPECIFIED: + return "TYPE_UNSPECIFIED"; + case ModelRegistrySchema_AllowedModel_Type.TYPE_CHECKPOINT: + return "TYPE_CHECKPOINT"; + case ModelRegistrySchema_AllowedModel_Type.TYPE_LORA: + return "TYPE_LORA"; + case ModelRegistrySchema_AllowedModel_Type.TYPE_EMBEDDING: + return "TYPE_EMBEDDING"; + case ModelRegistrySchema_AllowedModel_Type.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + +function createBasePersonaAssetSchema(): PersonaAssetSchema { + return { identity: undefined, personality: undefined, assets: undefined, metadata: undefined }; +} + +export const PersonaAssetSchema: MessageFns = { + encode(message: PersonaAssetSchema, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.identity !== undefined) { + PersonaAssetSchema_Identity.encode(message.identity, writer.uint32(10).fork()).join(); + } + if (message.personality !== undefined) { + PersonaAssetSchema_Personality.encode(message.personality, writer.uint32(18).fork()).join(); + } + if (message.assets !== undefined) { + PersonaAssetSchema_Assets.encode(message.assets, writer.uint32(26).fork()).join(); + } + if (message.metadata !== undefined) { + PersonaAssetSchema_Metadata.encode(message.metadata, writer.uint32(34).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PersonaAssetSchema { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePersonaAssetSchema(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.identity = PersonaAssetSchema_Identity.decode(reader, reader.uint32()); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.personality = PersonaAssetSchema_Personality.decode(reader, reader.uint32()); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.assets = PersonaAssetSchema_Assets.decode(reader, reader.uint32()); + continue; + } + case 4: { + if (tag !== 34) { + break; + } + + message.metadata = PersonaAssetSchema_Metadata.decode(reader, reader.uint32()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PersonaAssetSchema { + return { + identity: isSet(object.identity) ? PersonaAssetSchema_Identity.fromJSON(object.identity) : undefined, + personality: isSet(object.personality) ? PersonaAssetSchema_Personality.fromJSON(object.personality) : undefined, + assets: isSet(object.assets) ? PersonaAssetSchema_Assets.fromJSON(object.assets) : undefined, + metadata: isSet(object.metadata) ? PersonaAssetSchema_Metadata.fromJSON(object.metadata) : undefined, + }; + }, + + toJSON(message: PersonaAssetSchema): unknown { + const obj: any = {}; + if (message.identity !== undefined) { + obj.identity = PersonaAssetSchema_Identity.toJSON(message.identity); + } + if (message.personality !== undefined) { + obj.personality = PersonaAssetSchema_Personality.toJSON(message.personality); + } + if (message.assets !== undefined) { + obj.assets = PersonaAssetSchema_Assets.toJSON(message.assets); + } + if (message.metadata !== undefined) { + obj.metadata = PersonaAssetSchema_Metadata.toJSON(message.metadata); + } + return obj; + }, + + create, I>>(base?: I): PersonaAssetSchema { + return PersonaAssetSchema.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): PersonaAssetSchema { + const message = createBasePersonaAssetSchema(); + message.identity = (object.identity !== undefined && object.identity !== null) + ? PersonaAssetSchema_Identity.fromPartial(object.identity) + : undefined; + message.personality = (object.personality !== undefined && object.personality !== null) + ? PersonaAssetSchema_Personality.fromPartial(object.personality) + : undefined; + message.assets = (object.assets !== undefined && object.assets !== null) + ? PersonaAssetSchema_Assets.fromPartial(object.assets) + : undefined; + message.metadata = (object.metadata !== undefined && object.metadata !== null) + ? PersonaAssetSchema_Metadata.fromPartial(object.metadata) + : undefined; + return message; + }, +}; + +function createBasePersonaAssetSchema_Identity(): PersonaAssetSchema_Identity { + return { id: "", name: "", version: "", description: "" }; +} + +export const PersonaAssetSchema_Identity: MessageFns = { + encode(message: PersonaAssetSchema_Identity, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.version !== "") { + writer.uint32(26).string(message.version); + } + if (message.description !== "") { + writer.uint32(34).string(message.description); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PersonaAssetSchema_Identity { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePersonaAssetSchema_Identity(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.id = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.version = reader.string(); + continue; + } + case 4: { + if (tag !== 34) { + break; + } + + message.description = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PersonaAssetSchema_Identity { + return { + id: isSet(object.id) ? globalThis.String(object.id) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + version: isSet(object.version) ? globalThis.String(object.version) : "", + description: isSet(object.description) ? globalThis.String(object.description) : "", + }; + }, + + toJSON(message: PersonaAssetSchema_Identity): unknown { + const obj: any = {}; + if (message.id !== "") { + obj.id = message.id; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.version !== "") { + obj.version = message.version; + } + if (message.description !== "") { + obj.description = message.description; + } + return obj; + }, + + create, I>>(base?: I): PersonaAssetSchema_Identity { + return PersonaAssetSchema_Identity.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): PersonaAssetSchema_Identity { + const message = createBasePersonaAssetSchema_Identity(); + message.id = object.id ?? ""; + message.name = object.name ?? ""; + message.version = object.version ?? ""; + message.description = object.description ?? ""; + return message; + }, +}; + +function createBasePersonaAssetSchema_Personality(): PersonaAssetSchema_Personality { + return { traits: [], language: "", tone: "" }; +} + +export const PersonaAssetSchema_Personality: MessageFns = { + encode(message: PersonaAssetSchema_Personality, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.traits) { + writer.uint32(10).string(v!); + } + if (message.language !== "") { + writer.uint32(18).string(message.language); + } + if (message.tone !== "") { + writer.uint32(26).string(message.tone); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PersonaAssetSchema_Personality { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePersonaAssetSchema_Personality(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.traits.push(reader.string()); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.language = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.tone = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PersonaAssetSchema_Personality { + return { + traits: globalThis.Array.isArray(object?.traits) ? object.traits.map((e: any) => globalThis.String(e)) : [], + language: isSet(object.language) ? globalThis.String(object.language) : "", + tone: isSet(object.tone) ? globalThis.String(object.tone) : "", + }; + }, + + toJSON(message: PersonaAssetSchema_Personality): unknown { + const obj: any = {}; + if (message.traits?.length) { + obj.traits = message.traits; + } + if (message.language !== "") { + obj.language = message.language; + } + if (message.tone !== "") { + obj.tone = message.tone; + } + return obj; + }, + + create, I>>(base?: I): PersonaAssetSchema_Personality { + return PersonaAssetSchema_Personality.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): PersonaAssetSchema_Personality { + const message = createBasePersonaAssetSchema_Personality(); + message.traits = object.traits?.map((e) => e) || []; + message.language = object.language ?? ""; + message.tone = object.tone ?? ""; + return message; + }, +}; + +function createBasePersonaAssetSchema_Assets(): PersonaAssetSchema_Assets { + return { voiceProfileId: "", avatarId: "" }; +} + +export const PersonaAssetSchema_Assets: MessageFns = { + encode(message: PersonaAssetSchema_Assets, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.voiceProfileId !== "") { + writer.uint32(10).string(message.voiceProfileId); + } + if (message.avatarId !== "") { + writer.uint32(18).string(message.avatarId); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PersonaAssetSchema_Assets { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePersonaAssetSchema_Assets(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.voiceProfileId = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.avatarId = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PersonaAssetSchema_Assets { + return { + voiceProfileId: isSet(object.voiceProfileId) + ? globalThis.String(object.voiceProfileId) + : isSet(object.voice_profile_id) + ? globalThis.String(object.voice_profile_id) + : "", + avatarId: isSet(object.avatarId) + ? globalThis.String(object.avatarId) + : isSet(object.avatar_id) + ? globalThis.String(object.avatar_id) + : "", + }; + }, + + toJSON(message: PersonaAssetSchema_Assets): unknown { + const obj: any = {}; + if (message.voiceProfileId !== "") { + obj.voiceProfileId = message.voiceProfileId; + } + if (message.avatarId !== "") { + obj.avatarId = message.avatarId; + } + return obj; + }, + + create, I>>(base?: I): PersonaAssetSchema_Assets { + return PersonaAssetSchema_Assets.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): PersonaAssetSchema_Assets { + const message = createBasePersonaAssetSchema_Assets(); + message.voiceProfileId = object.voiceProfileId ?? ""; + message.avatarId = object.avatarId ?? ""; + return message; + }, +}; + +function createBasePersonaAssetSchema_Metadata(): PersonaAssetSchema_Metadata { + return { createdAt: undefined, updatedAt: undefined, tags: [] }; +} + +export const PersonaAssetSchema_Metadata: MessageFns = { + encode(message: PersonaAssetSchema_Metadata, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.createdAt !== undefined) { + Timestamp.encode(toTimestamp(message.createdAt), writer.uint32(10).fork()).join(); + } + if (message.updatedAt !== undefined) { + Timestamp.encode(toTimestamp(message.updatedAt), writer.uint32(18).fork()).join(); + } + for (const v of message.tags) { + writer.uint32(26).string(v!); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PersonaAssetSchema_Metadata { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePersonaAssetSchema_Metadata(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.createdAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.updatedAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.tags.push(reader.string()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PersonaAssetSchema_Metadata { + return { + createdAt: isSet(object.createdAt) + ? fromJsonTimestamp(object.createdAt) + : isSet(object.created_at) + ? fromJsonTimestamp(object.created_at) + : undefined, + updatedAt: isSet(object.updatedAt) + ? fromJsonTimestamp(object.updatedAt) + : isSet(object.updated_at) + ? fromJsonTimestamp(object.updated_at) + : undefined, + tags: globalThis.Array.isArray(object?.tags) ? object.tags.map((e: any) => globalThis.String(e)) : [], + }; + }, + + toJSON(message: PersonaAssetSchema_Metadata): unknown { + const obj: any = {}; + if (message.createdAt !== undefined) { + obj.createdAt = message.createdAt.toISOString(); + } + if (message.updatedAt !== undefined) { + obj.updatedAt = message.updatedAt.toISOString(); + } + if (message.tags?.length) { + obj.tags = message.tags; + } + return obj; + }, + + create, I>>(base?: I): PersonaAssetSchema_Metadata { + return PersonaAssetSchema_Metadata.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): PersonaAssetSchema_Metadata { + const message = createBasePersonaAssetSchema_Metadata(); + message.createdAt = object.createdAt ?? undefined; + message.updatedAt = object.updatedAt ?? undefined; + message.tags = object.tags?.map((e) => e) || []; + return message; + }, +}; + +function createBaseVoiceProfileSchema(): VoiceProfileSchema { + return { id: "", name: "", provider: 0, voiceId: "", settings: undefined, metadata: undefined }; +} + +export const VoiceProfileSchema: MessageFns = { + encode(message: VoiceProfileSchema, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.provider !== 0) { + writer.uint32(24).int32(message.provider); + } + if (message.voiceId !== "") { + writer.uint32(34).string(message.voiceId); + } + if (message.settings !== undefined) { + Struct.encode(Struct.wrap(message.settings), writer.uint32(42).fork()).join(); + } + if (message.metadata !== undefined) { + Struct.encode(Struct.wrap(message.metadata), writer.uint32(50).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VoiceProfileSchema { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVoiceProfileSchema(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.id = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 24) { + break; + } + + message.provider = reader.int32() as any; + continue; + } + case 4: { + if (tag !== 34) { + break; + } + + message.voiceId = reader.string(); + continue; + } + case 5: { + if (tag !== 42) { + break; + } + + message.settings = Struct.unwrap(Struct.decode(reader, reader.uint32())); + continue; + } + case 6: { + if (tag !== 50) { + break; + } + + message.metadata = Struct.unwrap(Struct.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): VoiceProfileSchema { + return { + id: isSet(object.id) ? globalThis.String(object.id) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + provider: isSet(object.provider) ? voiceProfileSchema_ProviderFromJSON(object.provider) : 0, + voiceId: isSet(object.voiceId) + ? globalThis.String(object.voiceId) + : isSet(object.voice_id) + ? globalThis.String(object.voice_id) + : "", + settings: isObject(object.settings) ? object.settings : undefined, + metadata: isObject(object.metadata) ? object.metadata : undefined, + }; + }, + + toJSON(message: VoiceProfileSchema): unknown { + const obj: any = {}; + if (message.id !== "") { + obj.id = message.id; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.provider !== 0) { + obj.provider = voiceProfileSchema_ProviderToJSON(message.provider); + } + if (message.voiceId !== "") { + obj.voiceId = message.voiceId; + } + if (message.settings !== undefined) { + obj.settings = message.settings; + } + if (message.metadata !== undefined) { + obj.metadata = message.metadata; + } + return obj; + }, + + create, I>>(base?: I): VoiceProfileSchema { + return VoiceProfileSchema.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): VoiceProfileSchema { + const message = createBaseVoiceProfileSchema(); + message.id = object.id ?? ""; + message.name = object.name ?? ""; + message.provider = object.provider ?? 0; + message.voiceId = object.voiceId ?? ""; + message.settings = object.settings ?? undefined; + message.metadata = object.metadata ?? undefined; + return message; + }, +}; + +function createBaseModelRegistrySchema(): ModelRegistrySchema { + return { llmModels: [], allowedModels: [] }; +} + +export const ModelRegistrySchema: MessageFns = { + encode(message: ModelRegistrySchema, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.llmModels) { + ModelRegistrySchema_LLMModel.encode(v!, writer.uint32(10).fork()).join(); + } + for (const v of message.allowedModels) { + ModelRegistrySchema_AllowedModel.encode(v!, writer.uint32(18).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ModelRegistrySchema { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseModelRegistrySchema(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.llmModels.push(ModelRegistrySchema_LLMModel.decode(reader, reader.uint32())); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.allowedModels.push(ModelRegistrySchema_AllowedModel.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ModelRegistrySchema { + return { + llmModels: globalThis.Array.isArray(object?.llmModels) + ? object.llmModels.map((e: any) => ModelRegistrySchema_LLMModel.fromJSON(e)) + : globalThis.Array.isArray(object?.llm_models) + ? object.llm_models.map((e: any) => ModelRegistrySchema_LLMModel.fromJSON(e)) + : [], + allowedModels: globalThis.Array.isArray(object?.allowedModels) + ? object.allowedModels.map((e: any) => ModelRegistrySchema_AllowedModel.fromJSON(e)) + : globalThis.Array.isArray(object?.allowed_models) + ? object.allowed_models.map((e: any) => ModelRegistrySchema_AllowedModel.fromJSON(e)) + : [], + }; + }, + + toJSON(message: ModelRegistrySchema): unknown { + const obj: any = {}; + if (message.llmModels?.length) { + obj.llmModels = message.llmModels.map((e) => ModelRegistrySchema_LLMModel.toJSON(e)); + } + if (message.allowedModels?.length) { + obj.allowedModels = message.allowedModels.map((e) => ModelRegistrySchema_AllowedModel.toJSON(e)); + } + return obj; + }, + + create, I>>(base?: I): ModelRegistrySchema { + return ModelRegistrySchema.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): ModelRegistrySchema { + const message = createBaseModelRegistrySchema(); + message.llmModels = object.llmModels?.map((e) => ModelRegistrySchema_LLMModel.fromPartial(e)) || []; + message.allowedModels = object.allowedModels?.map((e) => ModelRegistrySchema_AllowedModel.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseModelRegistrySchema_LLMModel(): ModelRegistrySchema_LLMModel { + return { id: "", provider: "", maxTokens: 0, temperature: 0 }; +} + +export const ModelRegistrySchema_LLMModel: MessageFns = { + encode(message: ModelRegistrySchema_LLMModel, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.provider !== "") { + writer.uint32(18).string(message.provider); + } + if (message.maxTokens !== 0) { + writer.uint32(24).uint32(message.maxTokens); + } + if (message.temperature !== 0) { + writer.uint32(37).float(message.temperature); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ModelRegistrySchema_LLMModel { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseModelRegistrySchema_LLMModel(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.id = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.provider = reader.string(); + continue; + } + case 3: { + if (tag !== 24) { + break; + } + + message.maxTokens = reader.uint32(); + continue; + } + case 4: { + if (tag !== 37) { + break; + } + + message.temperature = reader.float(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ModelRegistrySchema_LLMModel { + return { + id: isSet(object.id) ? globalThis.String(object.id) : "", + provider: isSet(object.provider) ? globalThis.String(object.provider) : "", + maxTokens: isSet(object.maxTokens) + ? globalThis.Number(object.maxTokens) + : isSet(object.max_tokens) + ? globalThis.Number(object.max_tokens) + : 0, + temperature: isSet(object.temperature) ? globalThis.Number(object.temperature) : 0, + }; + }, + + toJSON(message: ModelRegistrySchema_LLMModel): unknown { + const obj: any = {}; + if (message.id !== "") { + obj.id = message.id; + } + if (message.provider !== "") { + obj.provider = message.provider; + } + if (message.maxTokens !== 0) { + obj.maxTokens = Math.round(message.maxTokens); + } + if (message.temperature !== 0) { + obj.temperature = message.temperature; + } + return obj; + }, + + create, I>>(base?: I): ModelRegistrySchema_LLMModel { + return ModelRegistrySchema_LLMModel.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): ModelRegistrySchema_LLMModel { + const message = createBaseModelRegistrySchema_LLMModel(); + message.id = object.id ?? ""; + message.provider = object.provider ?? ""; + message.maxTokens = object.maxTokens ?? 0; + message.temperature = object.temperature ?? 0; + return message; + }, +}; + +function createBaseModelRegistrySchema_AllowedModel(): ModelRegistrySchema_AllowedModel { + return { id: "", type: 0, version: "" }; +} + +export const ModelRegistrySchema_AllowedModel: MessageFns = { + encode(message: ModelRegistrySchema_AllowedModel, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.type !== 0) { + writer.uint32(16).int32(message.type); + } + if (message.version !== "") { + writer.uint32(26).string(message.version); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ModelRegistrySchema_AllowedModel { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseModelRegistrySchema_AllowedModel(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.id = reader.string(); + continue; + } + case 2: { + if (tag !== 16) { + break; + } + + message.type = reader.int32() as any; + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.version = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ModelRegistrySchema_AllowedModel { + return { + id: isSet(object.id) ? globalThis.String(object.id) : "", + type: isSet(object.type) ? modelRegistrySchema_AllowedModel_TypeFromJSON(object.type) : 0, + version: isSet(object.version) ? globalThis.String(object.version) : "", + }; + }, + + toJSON(message: ModelRegistrySchema_AllowedModel): unknown { + const obj: any = {}; + if (message.id !== "") { + obj.id = message.id; + } + if (message.type !== 0) { + obj.type = modelRegistrySchema_AllowedModel_TypeToJSON(message.type); + } + if (message.version !== "") { + obj.version = message.version; + } + return obj; + }, + + create, I>>( + base?: I, + ): ModelRegistrySchema_AllowedModel { + return ModelRegistrySchema_AllowedModel.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): ModelRegistrySchema_AllowedModel { + const message = createBaseModelRegistrySchema_AllowedModel(); + message.id = object.id ?? ""; + message.type = object.type ?? 0; + message.version = object.version ?? ""; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; + +function toTimestamp(date: Date): Timestamp { + const seconds = Math.trunc(date.getTime() / 1_000); + const nanos = (date.getTime() % 1_000) * 1_000_000; + return { seconds, nanos }; +} + +function fromTimestamp(t: Timestamp): Date { + let millis = (t.seconds || 0) * 1_000; + millis += (t.nanos || 0) / 1_000_000; + return new globalThis.Date(millis); +} + +function fromJsonTimestamp(o: any): Date { + if (o instanceof globalThis.Date) { + return o; + } else if (typeof o === "string") { + return new globalThis.Date(o); + } else { + return fromTimestamp(Timestamp.fromJSON(o)); + } +} + +function isObject(value: any): boolean { + return typeof value === "object" && value !== null; +} + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create, I>>(base?: I): T; + fromPartial, I>>(object: I): T; +} diff --git a/locales/README.ja.md b/locales/README.ja.md index 3791d6a..0c7d21a 100644 --- a/locales/README.ja.md +++ b/locales/README.ja.md @@ -11,7 +11,7 @@ ![Rust LOD](https://img.shields.io/badge/Rust_LOD-187-dea584.svg) ![Mojo LOD](https://img.shields.io/badge/Mojo_LOD-176-CC0000.svg) ![Total LOD](https://img.shields.io/badge/Total_LOD-3476-brightgreen.svg) -[![Rust](https://img.shields.io/badge/Rust-dea584?logo=rust&logoColor=white)](./) [![Mojo](https://img.shields.io/badge/Mojo-CC0000?logo=mojo&logoColor=white)](./) [![buf](https://img.shields.io/badge/buf-151C3B)](./) [![Pixi](https://img.shields.io/badge/Pixi-F4A02D)](./) +[![Rust](https://img.shields.io/badge/Rust-dea584?logo=rust&logoColor=white)](https://www.rust-lang.org/) [![Mojo](https://img.shields.io/badge/Mojo-CC0000?logo=mojo&logoColor=white)](https://www.modular.com/mojo) [![buf](https://img.shields.io/badge/buf-151C3B)](https://buf.build/) [![Pixi](https://img.shields.io/badge/Pixi-F4A02D)](https://pixi.sh/) diff --git a/locales/README.th.md b/locales/README.th.md index fab9f3f..a177bd7 100644 --- a/locales/README.th.md +++ b/locales/README.th.md @@ -11,7 +11,7 @@ ![Rust LOD](https://img.shields.io/badge/Rust_LOD-187-dea584.svg) ![Mojo LOD](https://img.shields.io/badge/Mojo_LOD-176-CC0000.svg) ![Total LOD](https://img.shields.io/badge/Total_LOD-3476-brightgreen.svg) -[![Rust](https://img.shields.io/badge/Rust-dea584?logo=rust&logoColor=white)](./) [![Mojo](https://img.shields.io/badge/Mojo-CC0000?logo=mojo&logoColor=white)](./) [![buf](https://img.shields.io/badge/buf-151C3B)](./) [![Pixi](https://img.shields.io/badge/Pixi-F4A02D)](./) +[![Rust](https://img.shields.io/badge/Rust-dea584?logo=rust&logoColor=white)](https://www.rust-lang.org/) [![Mojo](https://img.shields.io/badge/Mojo-CC0000?logo=mojo&logoColor=white)](https://www.modular.com/mojo) [![buf](https://img.shields.io/badge/buf-151C3B)](https://buf.build/) [![Pixi](https://img.shields.io/badge/Pixi-F4A02D)](https://pixi.sh/) diff --git a/locales/README.zh.md b/locales/README.zh.md index fd33d8d..5e0d04f 100644 --- a/locales/README.zh.md +++ b/locales/README.zh.md @@ -11,7 +11,7 @@ ![Rust LOD](https://img.shields.io/badge/Rust_LOD-187-dea584.svg) ![Mojo LOD](https://img.shields.io/badge/Mojo_LOD-176-CC0000.svg) ![Total LOD](https://img.shields.io/badge/Total_LOD-3476-brightgreen.svg) -[![Rust](https://img.shields.io/badge/Rust-dea584?logo=rust&logoColor=white)](./) [![Mojo](https://img.shields.io/badge/Mojo-CC0000?logo=mojo&logoColor=white)](./) [![buf](https://img.shields.io/badge/buf-151C3B)](./) [![Pixi](https://img.shields.io/badge/Pixi-F4A02D)](./) +[![Rust](https://img.shields.io/badge/Rust-dea584?logo=rust&logoColor=white)](https://www.rust-lang.org/) [![Mojo](https://img.shields.io/badge/Mojo-CC0000?logo=mojo&logoColor=white)](https://www.modular.com/mojo) [![buf](https://img.shields.io/badge/buf-151C3B)](https://buf.build/) [![Pixi](https://img.shields.io/badge/Pixi-F4A02D)](https://pixi.sh/) diff --git a/proto/vtuber/v1/assets.proto b/proto/vtuber/v1/assets.proto new file mode 100644 index 0000000..6745f95 --- /dev/null +++ b/proto/vtuber/v1/assets.proto @@ -0,0 +1,84 @@ +syntax = "proto3"; + +package vtuber.v1; + +import "google/protobuf/timestamp.proto"; +import "google/protobuf/struct.proto"; + +// PersonaAssetSchema defines the configuration for a single VTuber persona. +// Used for validation of personas/*.toml files in vtuber-commons. +message PersonaAssetSchema { + message Identity { + string id = 1; + string name = 2; + string version = 3; + string description = 4; + } + + message Personality { + repeated string traits = 1; + string language = 2; + string tone = 3; + } + + message Assets { + string voice_profile_id = 1; + string avatar_id = 2; + } + + message Metadata { + google.protobuf.Timestamp created_at = 1; + google.protobuf.Timestamp updated_at = 2; + repeated string tags = 3; + } + + Identity identity = 1; + Personality personality = 2; + Assets assets = 3; + Metadata metadata = 4; +} + +// VoiceProfileSchema defines the configuration for a voice generation profile. +// Used for validation of voice_profiles/*.json files in vtuber-commons. +message VoiceProfileSchema { + enum Provider { + PROVIDER_UNSPECIFIED = 0; + PROVIDER_ELEVENLABS = 1; + PROVIDER_AZURE = 2; + PROVIDER_OPENAI = 3; + PROVIDER_COQUI = 4; + } + + string id = 1; + string name = 2; + Provider provider = 3; + string voice_id = 4; + google.protobuf.Struct settings = 5; + google.protobuf.Struct metadata = 6; +} + +// ModelRegistrySchema defines the allowed models and their configurations. +// Used for validation of models.yaml files in vtuber-commons. +message ModelRegistrySchema { + message LLMModel { + string id = 1; + string provider = 2; + uint32 max_tokens = 3; + float temperature = 4; + } + + message AllowedModel { + enum Type { + TYPE_UNSPECIFIED = 0; + TYPE_CHECKPOINT = 1; + TYPE_LORA = 2; + TYPE_EMBEDDING = 3; + } + string id = 1; + Type type = 2; + string version = 3; + } + + repeated LLMModel llm_models = 1; + repeated AllowedModel allowed_models = 2; +}