Kokoro Engine

September 18, 2026 · View on GitHub

Version: 2.1 Last updated: 2026-09-13 Transport: Tauri IPC (invoke) + Tauri events (emit / listen) Source of truth: src-tauri/src/lib.rs for registered commands, src/lib/kokoro-bridge.ts for frontend bridge wrappers Related doc: architecture.md


Table of contents

  1. Scope
  2. Calling convention
  3. Data types
  4. Command reference
  5. Event reference
  6. Custom protocols
  7. Error handling
  8. Bridge reference
  9. Compatibility notes
  10. Authenticated generic webhook

Scope

This document describes the current IPC surface of Kokoro Engine.

It covers:

  • commands registered in src-tauri/src/lib.rs
  • bridge wrappers exported from src/lib/kokoro-bridge.ts
  • public backend/bridge events and selected cross-window frontend events
  • custom URI schemes used by MODs, Live2D, and instance-owned character assets

It does not try to explain internal architecture. Use architecture.md for that.

2.1 command coverage supplement

The following commands were added after the original 2.0 inventory. Their serialized request and response shapes are defined by Rust command signatures and, where a wrapper exists, src/lib/kokoro-bridge.ts. They remain subject to the calling and error conventions in this document.

AreaCommands
Systemcheck_latest_release
Chat and profileis_chat_busy, get_user_profile_settings, set_user_persona
Character activationprepare_character_activation, commit_character_activation, get_committed_character_runtime
Character cataloglist_character_templates, instantiate_character_template, duplicate_character, restore_character_defaults, reconcile_character_template, apply_character_template_reconciliation, create_character_with_avatar, update_character_with_avatar
Character registrylist_registry_entries, install_character_from_registry, install_character_from_url, remove_character_package
Conversationsedit_conversation_message
Memory operationsrun_dream_now, get_dreaming_summary, list_dream_jobs, list_dream_proposals, approve_dream_proposal, reject_dream_proposal
Memory embedding and observabilityget_memory_embedding_model_status, download_memory_embedding_model, set_memory_upgrade_config, get_memory_upgrade_config, get_memory_observability_summary, get_latest_memory_write_event, get_latest_memory_retrieval_log, get_latest_memory_retrieval_eval_summary
LLMtest_llm_connection, list_anthropic_models, get_llama_cpp_status
Visionlist_vision_screens, set_vision_text_input_focused
Native audio streamprocess_audio_chunk, complete_audio_stream, discard_audio_stream, snapshot_audio_stream, prune_audio_buffer
MOD lifecycle and registryupdate_mod, remove_mod, install_mod_from_registry, install_mod_from_url
Unified Bot layerget_bot_config, save_bot_config, respond_qq_authorization, start_bot_platform, stop_bot_platform, get_bot_status
Pet windowtoggle_pet_window

This supplement makes the document inventory complete for the 171 unique frontend-invoked command names registered as of 2026-09-13. npm run check:ipc is the required automated consistency check; code remains authoritative if this narrative reference falls behind.


Calling convention

Commands

Frontend code calls backend commands with invoke:

import { invoke } from "@tauri-apps/api/core";

const info = await invoke("get_engine_info");

Most commands return Result<T, String> at the IPC boundary.

Events

Backend code pushes events with emit. Frontend code listens with listen.

import { listen } from "@tauri-apps/api/event";

const off = await listen("chat-turn-delta", (event) => {
  console.log(event.payload);
});

Naming

  • Rust command names use snake_case.
  • Bridge wrappers use camelCase.
  • Event names stay in the backend string form, such as chat-turn-delta.

Data types

This section lists the types that are part of the public bridge surface.

EngineInfo

interface EngineInfo {
  name: string;
  version: string;
  platform: string;
}

SystemStatus

interface SystemStatus {
  engine_running: boolean;
  active_modules: string[];
  memory_usage_mb: number;
}

CharacterState

interface CharacterState {
  name: string;
  current_cue: string;
  mood: number;
  is_speaking: boolean;
}

Note: mood is a legacy numeric runtime signal used by the current bridge, not the old emotion system.

ChatResponse

interface ChatResponse {
  text: string;
  cue: string;
  mood_delta: number;
}

Note: mood_delta is still part of the public bridge surface, but it should be treated as runtime state adjustment rather than an emotion subsystem API.

ChatRequest

interface ChatRequest {
  message: string;
  api_key?: string;
  endpoint?: string;
  model?: string;
  allow_image_gen?: boolean;
  images?: string[];
  character_id?: string;
  hidden?: boolean;
  client_request_id?: string;
  regenerate?: boolean;
  conversation_id?: string | null;
}

interface StreamChatResponse {
  conversation_id: string;
  user_message_id?: number | null;
  assistant_message_id?: number | null;
  client_request_id?: string | null;
  status?: "completed" | "cancelled" | string | null;
}

FailureEvent

interface FailureEventContext {
  deny_kind?: "hook_denied" | "policy_denied" | "fail_closed" | "pending_approval" | "execution_error";
  approval_status?: "requested" | "approved" | "rejected";
  [key: string]: unknown;
}

interface FailureEvent {
  event_id: string;
  timestamp: string;
  domain: string;
  stage: string;
  code: string;
  message: string;
  retryable: boolean;
  trace_id: string;
  conversation_id?: string | null;
  turn_id?: string | null;
  character_id?: string | null;
  context?: FailureEventContext | null;
}

The Rust failure payload includes the four nullable correlation/context keys. The bridge keeps them optional for compatibility, accepts the legacy string form from the raw chat-failure event, and normalizes the callback passed to onChatFailure to FailureEvent. Non-object context values are normalized to null by the bridge.

ChatTurnAcknowledgedEvent

interface ChatTurnAcknowledgedEvent {
  turn_id?: string;
  client_request_id?: string | null;
}

The current stream_chat backend always emits both keys as non-null strings. The optional and nullable markers preserve compatibility with older frontend event payloads.

ChatTurnStartEvent

interface ChatTurnStartEvent {
  turn_id: string;
  client_request_id?: string | null;
  conversation_id?: string | null;
  user_message_id?: number | null;
}

The current backend always emits all four keys: turn_id and client_request_id are strings, while conversation_id and user_message_id may be null. The bridge retains optional markers on the correlation fields for compatibility.

ChatTurnFinishEvent

interface ChatTurnFinishEvent {
  turn_id: string;
  status: "completed" | "error" | "cancelled";
  client_request_id?: string | null;
  conversation_id?: string | null;
  assistant_message_id?: number | null;
}

The current backend always emits all five keys: client_request_id is a string, and the conversation and assistant-message IDs may be null. The bridge retains optional markers on the correlation fields for compatibility.

ChatTurnTextCompleteEvent

interface ChatTurnTextCompleteEvent {
  turn_id: string;
  text: string;
  translation_pending: boolean;
  translation?: string | null;
}

The current backend always emits translation as either a string or null; older payloads may omit it. The bridge mirrors that runtime contract as translation?: string | null while retaining the optional marker for compatibility.

ContextSettings

interface ContextSettings {
  strategy: "window" | "summary";
  max_message_chars: number;
}

LlmConfig

interface LlmProviderConfig {
  id: string;
  provider_type: string;
  enabled: boolean;
  supports_native_tools: boolean;
  api_key?: string;
  api_key_env?: string;
  base_url?: string;
  model?: string;
  extra?: Record<string, unknown>;
}

interface LlmConfig {
  active_provider: string;
  system_provider?: string;
  system_model?: string;
  providers: LlmProviderConfig[];
  presets?: LlmPreset[];
}

TtsConfig

interface TtsConfig {
  provider_id?: string;
  api_key?: string;
  endpoint?: string;
  model?: string;
  voice?: string;
  speed?: number;
  pitch?: number;
  emotion?: string;
}

TtsSystemConfig

interface TtsSystemConfig {
  default_provider?: string | null;
  cache: {
    enabled: boolean;
    max_entries: number;
    ttl_secs: number;
  };
  queue: {
    max_concurrent: number;
  };
  providers: ProviderConfigData[];
}

VisionConfig

interface VisionConfig {
  vlm_enabled: boolean;
  auto_vision_enabled: boolean;
  vision_context_history_mode: "latest" | "full";
  capture_interval_secs: number;
  change_threshold: number;
  display_id?: string | null;
  vlm_region?: { x: number; y: number; width: number; height: number } | null;
  proactive_vision_enabled: boolean;
  vlm_provider: string;
  vlm_base_url: string | null;
  vlm_model: string;
  vlm_api_key: string | null;
  camera_enabled: boolean;
  camera_device_id: string | null;
}

ImageGenSystemConfig

interface ImageGenSystemConfig {
  default_provider?: string;
  enabled: boolean;
  providers: ImageGenProviderConfig[];
}

ImageGenParams

interface ImageGenParams {
  prompt: string;
  negative_prompt?: string;
  size?: string;
  quality?: string;
  style?: string;
  n: number;
}

ImageGenResult

interface ImageGenResult {
  image_url: string;
  prompt: string;
  provider_id: string;
}

SttConfig

interface SttConfig {
  active_provider: string;
  language?: string;
  auto_send: boolean;
  continuous_listening: boolean;
  wake_word_enabled: boolean;
  wake_word?: string;
  providers: SttProviderConfig[];
}

SenseVoiceLocalModelStatus

interface SenseVoiceLocalModelStatus {
  installed: boolean;
  download_instructions_url: string;
  recommended_model_id: string;
  download_url: string;
  install_dir: string;
  model_path: string;
  tokens_path: string;
}

SenseVoiceLocalDownloadProgress

interface SenseVoiceLocalDownloadProgress {
  stage: "downloading" | "extracting" | "complete" | "ready" | string;
  message: string;
  downloaded_bytes: number;
  total_bytes: number | null;
}

MemoryEmbeddingModelDownloadProgress

interface MemoryEmbeddingModelDownloadProgress {
  stage: string;
  message: string;
  current_file: string;
  file_index: number;
  file_count: number;
  downloaded_bytes: number;
  total_bytes: number | null;
}

Known stage values are checking, downloading, complete, verifying, and ready; consumers must tolerate additional string values.

ToolSettings

interface ToolSettings {
  max_tool_rounds: number;
  enabled_tools: Record<string, boolean>;
  max_permission_level: "safe" | "elevated";
  blocked_risk_tags: ("read" | "write" | "external" | "sensitive")[];
}

ActionInfo

interface ActionInfo {
  id: string;
  name: string;
  source: "builtin" | "mcp";
  server_name?: string;
  description: string;
  parameters: { name: string; description: string; required: boolean }[];
  needs_feedback: boolean;
  risk_tags: ("read" | "write" | "external" | "sensitive")[];
  permission_level: "safe" | "elevated";
}

ActionResult

interface ActionResult {
  success: boolean;
  message: string;
  data?: unknown;
}

McpServerConfig

interface McpServerConfig {
  name: string;
  type?: string;
  command?: string;
  args?: string[];
  env?: Record<string, string>;
  url?: string;
  enabled: boolean;
}

McpServerStatus

interface McpServerStatus {
  name: string;
  enabled: boolean;
  connected: boolean;
  tool_count: number;
  server_version: string | null;
  status: "connected" | "connecting" | "disconnected";
  error: string | null;
}

Conversation

interface Conversation {
  id: string;
  character_id: string;
  title: string;
  topic: string;
  pinned_state: string;
  created_at: string;
  updated_at: string;
}

LoadedConversation

interface LoadedConversation {
  topic: string;
  pinned_state: string;
  messages: ConversationMessage[];
}

MemoryRecord

interface MemoryRecord {
  id: number;
  content: string;
  created_at: number;
  importance: number;
  tier: string;
  memory_type: string;
  entity_key: string | null;
  status: string;
  confidence: number;
  first_seen_at: number;
  last_seen_at: number;
  evidence_count: number;
}

ListMemoriesResponse

interface ListMemoriesResponse {
  memories: MemoryRecord[];
  total: number;
}

Live2dModelInfo

interface Live2dModelInfo {
  name: string;
  path: string;
}

Live2dModelProfile

interface Live2dModelProfile {
  version: number;
  model_path: string;
  available_expressions: string[];
  available_motion_groups: Record<string, number>;
  available_hit_areas: string[];
  cue_map: Record<string, Live2dCueBinding>;
  semantic_cue_map: Record<string, string>;
}

ModManifest

interface ModManifest {
  id: string;
  name: string;
  version: string;
  description: string;
  engine_version?: string;
  layout?: string;
  theme?: string;
  components?: Record<string, string>;
  scripts?: string[];
  permissions?: string[];
  entry?: string;
  ui_entry?: string;
}

ModThemeJson

interface ModThemeJson {
  id?: string;
  name?: string;
  variables: Record<string, string>;
  assets?: {
    fonts?: string[];
    background?: string;
    noise_texture?: string;
    [key: string]: string | string[] | undefined;
  };
  animations?: Record<string, {
    initial?: Record<string, number | string>;
    animate?: Record<string, number | string>;
    exit?: Record<string, number | string>;
    transition?: Record<string, number | string>;
  }>;
}

TelegramConfig

interface TelegramConfig {
  enabled: boolean;
  bot_token?: string;
  bot_token_env?: string;
  allowed_chat_ids: number[];
  send_voice_reply: boolean;
  character_id?: string;
}

WebhookMessageRequest

interface WebhookMessageRequest {
  text?: string;
  message?: string;                 // legacy alias for text
  image?: string;                   // URL or base64 payload
  images?: string[];                // URLs or base64 payloads
  image_base64?: string;
  image_mime_type?: string;         // defaults to image/jpeg for raw base64
  audio_base64?: string;            // raw or data: base64 payload
  audio_format?: string;            // ogg, mp3, wav, webm, or m4a
  character_id?: string;
  conversation_id?: string;
  conversation_type?: "private" | "group" | "channel";
  user_id?: string;
  source?: string;
}

text takes precedence over message. A request may contain text, image media, audio, or any combination. Audio is transcribed by the configured STT service before the request is sent to the LLM. An image-only request uses the placeholder The user sent an image: when no caption is supplied.

WebhookReply

interface WebhookReply {
  reply: string;
  translation?: string;
  images?: Array<{
    prompt: string;
    mime_type: string;
    file_name: string;
    data_base64: string;
  }>;
  audio?: {
    mime_type: string;
    file_name: string;
    data_base64: string;
  };
}

TelegramStatus

interface TelegramStatus {
  running: boolean;
  enabled: boolean;
  has_token: boolean;
}

BackupStats

interface BackupStats {
  memories: number;
  conversations: number;
  messages: number;
  configs: number;
}

ExportResult

interface ExportResult {
  path: string;
  size_bytes: number;
  stats: BackupStats;
}

BackupManifest

interface BackupManifest {
  version: string;
  created_at: string;
  app_version: string;
}

ImportPreview

interface ImportPreview {
  manifest: BackupManifest;
  has_database: boolean;
  has_configs: boolean;
  config_files: string[];
  stats: BackupStats;
  /** Character instances stored in the backup; empty for pre-SQLite-character backups. */
  characters: BackupCharacterSummary[];
}

interface BackupCharacterSummary {
  id: string;
  name: string;
  memory_count: number;
  conversation_count: number;
}

ImportOptions

Character instance ids are generated per machine, so a backup never reuses a local id. character_merges routes the rows of a backup character into an existing local instance, ignored_characters leaves them out of the restore entirely, and every character that appears in neither list is imported as a new instance. All ids are validated before the first live row is touched; a character cannot be merged and ignored at the same time.

interface ImportOptions {
  import_database: boolean;
  import_configs: boolean;
  conflict_strategy: "skip" | "overwrite";
  character_merges?: CharacterMerge[];
  ignored_characters?: string[];
}

interface CharacterMerge {
  /** Character id as stored inside the backup. */
  imported_id: string;
  /** Existing local character that receives the imported rows. */
  target_id: string;
}

ImportResult

interface ImportResult {
  imported_memories: number;
  imported_conversations: number;
  imported_configs: number;
  imported_characters: number;
  /** Characters whose rows were routed into an existing local instance. */
  merged_characters?: number;
  /** Characters whose rows were left out of the restore. */
  ignored_characters?: number;
  /** Memories dropped by the skip strategy because they violate the local schema. */
  skipped_memories?: number;
  characters_json?: string;
  debug_log?: string[];
}

CharacterRecord

interface CharacterRecord {
  id: string;
  name: string;
  persona: string;
  user_nickname: string;
  source_format: string;
  created_at: number;
  updated_at: number;
  template_id?: string | null;
  template_version?: string | null;
  template_snapshot_json?: string | null;
  description?: string;
  avatar_path?: string | null;
  greeting?: string;
  greeting_consumed_at?: number | null;
  greeting_message_id?: number | null;
  example_dialogue?: string;
  runtime_profile_json?: string;
  user_modified_at?: number | null;
}

AutoBackupConfig

interface AutoBackupConfig {
  enabled: boolean;
  backup_dir: string;
  interval_days: number;
  auto_cleanup: boolean;
  keep_days: number;
}

Command reference

The tables below list the current IPC commands. The Bridge column shows whether src/lib/kokoro-bridge.ts exports a wrapper for the command.

System

CommandBridgeRequestResponseNotes
get_engine_infogetEngineInfononeEngineInfoReturns app metadata.
get_system_statusgetSystemStatusnoneSystemStatusReturns runtime status.
set_window_sizesetWindowSizewidth: number, height: numbervoidStores the current UI size for image generation.

Character

CommandBridgeRequestResponseNotes
get_character_stategetCharacterStatenoneCharacterStateReturns the current character state.
play_cueplayCuecue: stringCharacterStateUpdates the active cue.
send_messagesendMessagemessage: stringChatResponseLegacy non-streaming chat entry point.

Database

CommandBridgeRequestResponseNotes
init_dbinitDbnonestringInitializes the SQLite database.
test_vector_storetestVectorStorenoneDbTestResultSmoke test for memory storage.

Context

CommandBridgeRequestResponseNotes
set_personasetPersonaprompt: stringvoidSets the system prompt.
set_character_namesetCharacterNamename: stringvoidSets the character display name.
set_active_character_idsetActiveCharacterIdid: stringvoidPersists the active character id.
set_user_namesetUserNamename: stringvoidSets the user name used in prompts.
set_response_languagesetResponseLanguagelanguage: stringvoidSets assistant response language.
set_user_languagesetUserLanguagelanguage: stringvoidSets user language.
set_jailbreak_promptsetJailbreakPromptprompt: stringvoidPersists the jailbreak prompt.
get_jailbreak_promptgetJailbreakPromptnonestringReturns the current jailbreak prompt.
set_proactive_enabledsetProactiveEnabledenabled: booleanvoidEnables or disables proactive messages.
get_proactive_enabledgetProactiveEnablednonebooleanReturns proactive toggle state.
set_memory_enabledsetMemoryEnabledenabled: booleanvoidEnables or disables memory persistence.
get_memory_enabledgetMemoryEnablednonebooleanReturns memory toggle state.
clear_historyclearHistorynonevoidClears conversation history.
delete_last_messagesdeleteLastMessagescount: number, expectedConversationId?: string | nullvoidDeletes the last visible messages. Skipped (no-op) when expectedConversationId does not match the backend's current conversation, preventing stale deletes after a conversation switch.
get_context_settingsgetContextSettingsnoneContextSettingsReturns chat context strategy settings.
set_context_settingssetContextSettingssettings: ContextSettingsvoidSaves chat context strategy settings.
end_sessionnonerequest: EndSessionRequestvoidGenerates a summary in the background and clears history.

LLM management

CommandBridgeRequestResponseNotes
get_llm_configgetLlmConfignoneLlmConfigReturns the active LLM config.
save_llm_configsaveLlmConfigconfig: LlmConfigvoidSaves the active LLM config.
get_codex_runtime_statusgetCodexRuntimeStatusnoneCodexRuntimeInfoDetects a local Codex CLI; does not read Codex credentials.
list_codex_runtime_modelslistCodexRuntimeModelsnonestring[]Queries the Codex app-server model/list RPC.
list_ollama_modelslistOllamaModelsbaseUrl: stringOllamaModelInfo[]Lists models from an Ollama server.

Chat

CommandBridgeRequestResponseNotes
stream_chatstreamChatrequest: ChatRequestStreamChatResponseStreaming chat entry point. Emits turn events and returns persisted message identifiers/status.
cancel_chat_turncancelChatTurnturnId: string, reason?: stringvoidCancels an in-flight turn.
approve_tool_approvalapproveToolApprovalapprovalRequestId: stringvoidApproves a pending tool execution.
reject_tool_approvalrejectToolApprovalapprovalRequestId: string, reason?: stringvoidRejects a pending tool execution.

TTS

CommandBridgeRequestResponseNotes
synthesizesynthesizetext: string, config: TtsConfigvoidStreams audio through TTS events.
list_tts_providerslistTtsProvidersnoneProviderStatus[]Lists configured TTS providers.
list_tts_voiceslistTtsVoicesnoneVoiceProfile[]Lists available voices.
get_tts_provider_statusgetTtsProviderStatusproviderId: stringProviderStatus | nullReturns one provider's status.
clear_tts_cacheclearTtsCachenonevoidClears the synthesis cache.
get_tts_configgetTtsConfignoneTtsSystemConfigReturns the TTS system config.
save_tts_configsaveTtsConfigconfig: TtsSystemConfigvoidSaves the TTS system config.
list_gpt_sovits_modelslistGptSovitsModelsinstallPath: stringGptSovitsModelsLists GPT-SoVITS models.

Mod system

CommandBridgeRequestResponseNotes
list_modslistModsnoneModManifest[]Lists discovered mods.
load_modloadModmodId: stringModManifestLoads and activates a mod.
install_modinstallModfilePath: stringModManifestInstalls a mod archive.
get_mod_themegetModThemenoneModThemeJson | nullReturns the active mod theme override.
get_mod_layoutgetModLayoutnoneunknown | nullReturns the active mod layout override.
dispatch_mod_eventdispatchModEventevent: string, payload: unknownvoidSends an event into the active mod.
unload_modunloadModnonevoidUnloads the active mod.

Live2D

CommandBridgeRequestResponseNotes
import_live2d_zipimportLive2dZipzipPath: stringstringImports a Live2D archive.
import_live2d_folderimportLive2dFoldermodelJsonPath: stringstringImports a Live2D folder from a model JSON path.
export_live2d_modelexportLive2dModelmodelPath: string, exportPath: stringstringExports a Live2D model.
list_live2d_modelslistLive2dModelsnoneLive2dModelInfo[]Lists installed models.
delete_live2d_modeldeleteLive2dModelmodelName: stringvoidDeletes a model.
rename_live2d_modelrenameLive2dModelmodelPath: string, newName: stringstringRenames a model.
get_live2d_model_profilegetLive2dModelProfilemodelPath: stringLive2dModelProfileReturns the cue/profile mapping.
save_live2d_model_profilesaveLive2dModelProfileprofile: Live2dModelProfileLive2dModelProfileSaves the profile and returns the merged profile.
set_active_live2d_modelsetActiveLive2dModelmodelPath: string | nullvoidSets the active model.

Image generation

CommandBridgeRequestResponseNotes
generate_imagegenerateImageprompt: string, providerId?: stringImageGenResultBridge wrapper only exposes prompt and provider selection. The backend builds the rest from config and window size state.
get_imagegen_configgetImageGenConfignoneImageGenSystemConfigReturns image generation config.
save_imagegen_configsaveImageGenConfigconfig: ImageGenSystemConfigvoidSaves image generation config.
test_sd_connectiontestSdConnectionbaseUrl: stringstring[]Returns Stable Diffusion model names from the server.

Vision

CommandBridgeRequestResponseNotes
start_vision_watchernonenonevoidStarts the background watcher.
stop_vision_watchernonenonevoidStops the background watcher.
capture_screen_nowcaptureScreenNownonestringCaptures the screen and returns a description.
upload_vision_imageuploadVisionImagefileBytes: number[], filename: stringstringUploads an image to the vision server.
get_vision_configgetVisionConfignoneVisionConfigReturns the vision watcher config.
save_vision_configsaveVisionConfigconfig: VisionConfigvoidSaves config and starts/stops the watcher.

Memory

CommandBridgeRequestResponseNotes
list_memorieslistMemoriesrequest: { character_id: string; limit: number; offset: number }ListMemoriesResponseLists memories for one character.
update_memoryupdateMemoryrequest: { id: number; content: string; importance: number }voidUpdates a memory record.
delete_memorydeleteMemoryrequest: { id: number }voidDeletes a memory record.
update_memory_tierupdateMemoryTierrequest: { id: number; tier: string }voidUpdates the memory tier.

Characters

CommandBridgeRequestResponseNotes
list_characterslistCharactersnoneCharacterRecord[]Lists stored characters.
create_charactercreateCharacterrequest: CharacterRecordvoidCreates a character row.
update_characterupdateCharacterrequest: Omit<CharacterRecord, "created_at">voidUpdates a character row.
delete_characterdeleteCharacterid: stringvoidDeletes a character row.

Conversation

CommandBridgeRequestResponseNotes
list_conversationslistConversationsrequest: { character_id: string }Conversation[]Lists conversations for one character.
load_conversationloadConversationrequest: { id: string }LoadedConversationLoads a conversation.
update_conversation_stateupdateConversationStaterequest: { id: string; topic?: string; pinned_state?: string }voidUpdates topic or pinned state.
delete_conversationdeleteConversationrequest: { id: string }voidDeletes a conversation.
create_conversationcreateConversationnonestringCreates a new conversation id.
rename_conversationrenameConversationrequest: { id: string; title: string }voidRenames a conversation.
list_character_idslistCharacterIdsnonestring[]Lists known character ids.

STT

CommandBridgeRequestResponseNotes
transcribe_audiotranscribeAudioaudioBytes: number[], format: stringstringTranscribes one audio clip.
get_stt_configgetSttConfignoneSttConfigReturns STT config.
save_stt_configsaveSttConfigconfig: SttConfigvoidSaves STT config.
transcribe_wake_word_audiononesamples: Vec<f32>stringShort one-shot transcription for wake-word detection.
start_native_micnoneauto_stop_on_silence?: booleanvoidStarts the native microphone worker.
stop_native_micnonenonevoidStops the native microphone worker.
start_native_wake_wordnonewake_word: string, trigger_on_speech?: booleanvoidStarts the native wake-word worker.
stop_native_wake_wordnonenonevoidStops the native wake-word worker.
get_sensevoice_local_statusgetSenseVoiceLocalStatusnoneSenseVoiceLocalModelStatusReturns the recommended local SenseVoice status.
download_sensevoice_local_modeldownloadSenseVoiceLocalModelnoneSenseVoiceLocalModelStatusDownloads the recommended local model.

Actions

CommandBridgeRequestResponseNotes
list_actionslistActionsnoneActionInfo[]Lists all actions.
list_builtin_toolslistBuiltinToolsnoneActionInfo[]Lists only builtin tools.
execute_actionexecuteActionname: string, args: Record<string, string>, characterId?: stringActionResultExecutes one action.
get_tool_settingsgetToolSettingsnoneToolSettingsReturns tool settings.
save_tool_settingssaveToolSettingssettings: ToolSettingsvoidSaves tool settings.
approve_tool_approvalapproveToolApprovalapprovalRequestId: stringvoidApproval flow for pending tools.
reject_tool_approvalrejectToolApprovalapprovalRequestId: string, reason?: stringvoidApproval flow for pending tools.

MCP

CommandBridgeRequestResponseNotes
list_mcp_serverslistMcpServersnoneMcpServerStatus[]Lists configured servers with live status.
add_mcp_serveraddMcpServerconfig: McpServerConfigvoidAdds a server and connects in background.
remove_mcp_serverremoveMcpServername: stringvoidRemoves a server.
refresh_mcp_toolsrefreshMcpToolsnonevoidRebuilds the tool registry from connected servers.
reconnect_mcp_serverreconnectMcpServername: stringvoidReconnects one server.
toggle_mcp_servertoggleMcpServername: string, enabled: booleanvoidEnables or disables a server.

Telegram

CommandBridgeRequestResponseNotes
get_telegram_configgetTelegramConfignoneTelegramConfigReturns Telegram config.
save_telegram_configsaveTelegramConfigconfig: TelegramConfigvoidSaves Telegram config.
start_telegram_botstartTelegramBotnonevoidStarts the bot.
stop_telegram_botstopTelegramBotnonevoidStops the bot.
get_telegram_statusgetTelegramStatusnoneTelegramStatusReturns runtime bot status.

Backup and restore

CommandBridgeRequestResponseNotes
export_dataexportDataexportPath: string, charactersJson?: stringExportResultExports database and configs into a .kokoro archive.
preview_importpreviewImportfilePath: stringImportPreviewReads archive metadata without importing.
import_dataimportDatafilePath: string, options: ImportOptionsImportResultImports data from a .kokoro archive.
get_auto_backup_configgetAutoBackupConfignoneAutoBackupConfigReturns auto backup config.
save_auto_backup_configsaveAutoBackupConfigconfig: AutoBackupConfigvoidSaves auto backup config.
run_auto_backup_nowrunAutoBackupNownonestringRuns a backup immediately.

Authenticated generic webhook

The optional generic webhook is served by the Bot HTTP runtime. Its endpoint defaults to http://127.0.0.1:8787/webhook/message and can be changed in the Webhook settings. It must be enabled before requests are accepted. Requests are limited to 4 MiB; larger bodies are rejected before authentication and JSON parsing.

When a bearer token is configured, clients must send:

Authorization: Bearer <configured-token>
Content-Type: application/json

The character selection order is request character_id, configured Webhook default character, then the active Kokoro character. Blank values are ignored; no provider credentials or filesystem paths are accepted in the request.

Private and group sessions are isolated per character before persistence. A private request maps user_id (falling back to conversation_id or source) to private:<identity>. A group or channel request maps conversation_id (falling back to source or user_id) to group:<identity>. The resulting identity is scoped to the resolved character and reused on subsequent requests.

Successful requests return WebhookReply with HTTP 200. Missing or invalid JSON, invalid base64, and requests without text or media return HTTP 400 with {"error":"..."}. Missing or invalid bearer credentials return HTTP 401 with the same JSON error shape. LLM, STT, or other runtime failures return HTTP 500.

Example text request:

curl -X POST http://127.0.0.1:8787/webhook/message \
  -H "Authorization: Bearer $KOKORO_WEBHOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text":"Hello Kokoro","user_id":"astrbot-user-1","conversation_type":"private"}'

Example group image request:

{
  "text": "What do you see?",
  "images": ["https://example.test/photo.png"],
  "conversation_type": "group",
  "conversation_id": "astrbot-group-7",
  "character_id": "kokoro"
}

Commands registered in Rust but not exposed by the bridge

These commands exist in src-tauri/src/lib.rs, but src/lib/kokoro-bridge.ts does not export wrappers for them yet.

CommandModuleNotes
end_sessioncontextSummarizes the current session in the background.
start_vision_watchervisionStarts the background vision loop.
stop_vision_watchervisionStops the background vision loop.
transcribe_wake_word_audiosttOne-shot wake-word transcription.
start_native_micsttStarts the native microphone worker.
stop_native_micsttStops the native microphone worker.
start_native_wake_wordsttStarts the wake-word worker.
stop_native_wake_wordsttStops the wake-word worker.
show_pet_windowpetShows the floating pet window.
hide_pet_windowpetHides the floating pet window.
set_pet_drag_modepetToggles pet drag mode.
get_pet_configpetReturns pet window config.
save_pet_configpetSaves pet window config.
move_pet_windowpetMoves the pet window.
resize_pet_windowpetResizes the pet window.
show_bubble_windowpetShows the speech bubble window.
update_bubble_textpetUpdates the bubble text.
hide_bubble_windowpetHides the speech bubble window.
toggle_pet_windowpetToggles the floating pet window.
process_audio_chunkstt::streamAppends data to a native audio stream.
complete_audio_streamstt::streamCompletes and transcribes a native audio stream.
discard_audio_streamstt::streamDiscards a native audio stream.
snapshot_audio_streamstt::streamReturns an audio-stream snapshot.
prune_audio_bufferstt::streamPrunes buffered native audio.
check_latest_releasesystemChecks release metadata.
update_modmodsUpdates an installed MOD.
remove_modmodsRemoves an installed MOD package.
install_mod_from_urlmodsInstalls an untrusted MOD URL after the caller's confirmation flow.

Event reference

Chat events

EventPayloadEmitted byBridge wrapper
chat-typingTypingParamschat.rsnone
chat-turn-startChatTurnStartEventchat.rsonChatTurnStart
chat-turn-delta{ turn_id: string; delta: string; ... }chat.rsonChatTurnDelta
chat-turn-finishChatTurnFinishEventchat.rsonChatTurnFinish
chat-turn-translation{ turn_id: string; translation: string }chat.rsonChatTurnTranslation
chat-turn-toolToolTraceItem-style payloadchat.rsonChatTurnTool
chat-cue{ cue: string; source?: string }chat.rs, mods/manager.rsonChatCue
chat-imagegen{ prompt: string }actions/builtin.rsonChatImageGen
chat-errorstringchat.rsonChatError
chat-warningstringchat.rsonChatWarning
chat-failureFailureEvent | stringchat.rsonChatFailure
chat-turn-acknowledgedChatTurnAcknowledgedEventchat.rsonChatTurnAcknowledged
chat-turn-text-completeChatTurnTextCompleteEventchat.rsonChatTurnTextComplete

TTS events

EventPayloadEmitted byBridge wrapper
tts:start{ text: string }tts/manager.rsnone
tts:audio{ data: number[] }tts/manager.rsnone
tts:end{ text: string }tts/manager.rsnone
tts:browser-delegate{ text: string; voice?: string; speed?: number; pitch?: number }tts/manager.rsnone

Vision events

EventPayloadEmitted byBridge wrapper
vision-status"active" | "inactive"vision/watcher.rsnone
vision-observationstring | { summary: string; captured_at?: string; source?: string }vision/watcher.rsonVisionObservation
camera-observationstringlistener only; producer is not present in tracked sourcesonCameraObservation
proactive-trigger{ trigger: string; instruction: string; idle_seconds?: number }vision/watcher.rs, ai/heartbeat.rsnone

STT events

EventPayloadEmitted byBridge wrapper
stt:sensevoice-local-progressSenseVoiceLocalDownloadProgresscommands/stt.rsonSenseVoiceLocalProgress
stt:mic-volume{ volume: number; rms: number }stt/mic.rsnone
stt:mic-auto-stop()stt/mic.rsnone
stt:wake-word-detectedstringstt/wake_word.rsnone
stt:wake-word-errorstringstt/wake_word.rsnone

Idle and proactive events

EventPayloadEmitted byBridge wrapper
idle-behavior{ behavior: unknown }ai/heartbeat.rsnone

Live2D and MOD events

EventPayloadEmitted byBridge wrapper
live2d-profile-updatedLive2dModelProfile-style payloadcommands/live2d.rsnone
live2d-model-selection-updatedLive2dSelectionEventfrontend/runtimenone
character-runtime-committedCommittedCharacterRuntimecharacter activationnone
pet-config-updatedPetConfigpet settings/windownone
qq-authorization-request / qq-authorization-expiredQQAuthorizationRequestqqbot/runtime.rsnone
qq-authorization-approvedauthorization result payloadcommands/bot.rsnone
mod:theme-overrideModThemeJsonmods/manager.rsonModThemeOverride
mod:layout-overrideunknownmods/manager.rsonModLayoutOverride
mod:components-registerRecord<string, string>mods/manager.rsonModComponentsRegister
mod:ui-message{ component: string; payload: unknown }mods/manager.rsonModUiMessage
mod:unload()mods/manager.rsonModUnload
mod:script-event{ event: string; payload: unknown }mods/api.ts bridge pathonModScriptEvent

Image generation events

EventPayloadEmitted byBridge wrapper
imagegen:doneImageGenResultchat.rsonImageGenDone
imagegen:errorstringchat.rsonImageGenError

Telegram events

EventPayloadEmitted byBridge wrapper
telegram:chat-sync{ role: string; text: string; translation?: string }telegram/bot.rsonTelegramChatSync

Backup and memory events

EventPayloadEmitted byBridge wrapper
memory:updatedstringactions/builtin.rsnone
memory:embedding-model-progressMemoryEmbeddingModelDownloadProgresscommands/memory.rsonMemoryEmbeddingModelProgress
pet-window-closed()commands/pet.rsnone
bubble-text-updatestringcommands/pet.rsnone
toggle-chat-input()lib.rsnone

Custom protocols

mod://

Serves MOD assets from the installed mods/ directory.

  • HTML files are served with the MOD SDK injected automatically.
  • Path traversal is blocked.
  • The response sets a strict Content Security Policy.
  • CORS is limited to the app origin.

Example:

<img src="mod://example-mod/assets/icon.png" />
<script src="mod://example-mod/index.js"></script>

live2d://

Serves Live2D runtime assets from {app_data_dir}/live2d_models/.

  • Path traversal is blocked.
  • The protocol resolves files relative to the app data directory.
  • It supports the runtime file layout expected by pixi-live2d-display.

Example:

live2d://localhost/my-model/runtime/model3.json

character-instance-resource://

Serves the managed PNG avatar owned by a character instance from {app_data_dir}/character-instance-resources/<instance_id>/avatar.png.

  • The canonical reference is character-instance-resource://<instance_id>/avatar.png.
  • On Windows WebView2 it is mapped to http://character-instance-resource.localhost/<instance_id>/avatar.png.
  • The instance ID must contain 1–128 ASCII letters, digits, hyphens, or underscores, and the only accepted relative path is avatar.png.
  • The handler rejects a redirected resource root and canonicalizes the requested file to enforce containment within that root.
  • Successful responses use Content-Type: image/png, Cache-Control: no-store, and Access-Control-Allow-Origin: *.

Example:

<img src="character-instance-resource://example-character/avatar.png" />

Error handling

IPC error shape

Most commands return Result<T, String> at the IPC boundary.

The backend uses KokoroError internally. KokoroError serializes as:

{
  code: string;
  message: string;
}

If serialization fails, the backend falls back to a plain string.

Common failures

CommandErrorCondition
send_messageMessage cannot be emptyBlank message input
stream_chatAPI Key is requiredMissing API key for direct API calls
synthesizeNo TTS provider availableNo provider is configured
synthesizeProvider {id} not foundSelected provider does not exist
run_auto_backup_nowBackup directory not setAuto backup directory is empty
load_conversationNotFound-style errorConversation id does not exist

Frontend pattern

try {
  await streamChat({
    message: "Hello",
    api_key: "sk-...",
  });
} catch (error) {
  console.error("command failed", error);
}

If you want structured handling, use parseKokoroError from kokoro-bridge.ts.


Bridge reference

src/lib/kokoro-bridge.ts is the typed frontend entry point.

Exported command wrappers

  • system: getEngineInfo, getSystemStatus, setWindowSize
  • character: getCharacterState, playCue
  • database: initDb, testVectorStore, sendMessage
  • context: setPersona, setCharacterName, setActiveCharacterId, setUserName, setResponseLanguage, setUserLanguage, setJailbreakPrompt, getJailbreakPrompt, setProactiveEnabled, getProactiveEnabled, clearHistory, setMemoryEnabled, getMemoryEnabled, getContextSettings, setContextSettings, deleteLastMessages
  • llm/chat: getLlmConfig, saveLlmConfig, getCodexRuntimeStatus, listCodexRuntimeModels, listOllamaModels, streamChat, cancelChatTurn, approveToolApproval, rejectToolApproval
  • mod/live2d/imagegen/vision/memory/stt/actions/mcp/telegram/backup/characters: see the command tables above

Exported event wrappers

  • chat: onChatError, onChatWarning, onChatFailure, onChatTurnStart, onChatTurnAcknowledged, onChatTurnDelta, onChatTurnTextComplete, onChatTurnFinish, onChatTurnTranslation, onChatCue, onChatTurnTool
  • mod: onModThemeOverride, onModLayoutOverride, onModComponentsRegister, onModUiMessage, onModUnload, onModScriptEvent
  • imagegen: onChatImageGen, onImageGenDone, onImageGenError
  • vision: onVisionObservation, onCameraObservation
  • STT/memory: onSenseVoiceLocalProgress, onMemoryEmbeddingModelProgress
  • telegram: onTelegramChatSync

Bridge-only helpers

These are local TypeScript helpers and not IPC commands:

  • fetchModels
  • hasPinnedConversationState
  • getConversationDisplayTitle
  • parseKokoroError
  • safeInvoke
  • isKokoroErrorCode

Compatibility notes

Old entries removed from the previous spec

The following items in the old document no longer match the current code and should not be treated as current API:

  • old ChatRequest shape without image support
  • old ToolSettings shape without permission/risk controls
  • old TTS / STT / ImageGen / MCP return types that no longer match the bridge
  • old quick reference entries that returned Uint8Array for streaming APIs
  • other legacy entries that were removed during the bridge cleanup and are no longer exported by src/lib/kokoro-bridge.ts

Bridge coverage

Not every backend command has a bridge wrapper yet. The command tables above mark those gaps explicitly.

Event coverage

Some events are emitted by the backend but do not yet have dedicated bridge helpers. That is intentional. The backend event string is still the contract.


Appendix

Backend modules used by this document

  • src-tauri/src/lib.rs
  • src-tauri/src/commands/*.rs
  • src-tauri/src/tts/manager.rs
  • src-tauri/src/vision/watcher.rs
  • src-tauri/src/stt/*.rs
  • src-tauri/src/mods/*.rs
  • src-tauri/src/ai/*.rs
  • src/lib/kokoro-bridge.ts
  • src/core/types/mod.ts