Commit Graph
2005 Commits
Author SHA1 Message Date
Makito 7c76ea680c chore(pnpm): fix pnpm-workspaces issues and update catalog for vitest 2026-05-20 11:38:20 +09:00
Makito f86d86c04c feat(stage-tamagotchi,stage-shared): listen keyup for global shortcut with uiohook 2026-05-20 03:07:54 +09:00
Neko Ayaka 10f340a651 fix(stage-ui): missing and incorrect flex gap 2026-05-20 01:46:18 +08:00
RainbowBird 615e0441e8 refactor(server): proxy TTS through unspeech, drop implicit fallbacks
Frontend voice picker silently lost Azure voices because /audio/voices
was called without ?model=, so the server fell back to DEFAULT_TTS_MODEL
and only ever returned one model's catalog. /audio/models also hardcoded
a single `auto` alias, so the client could never request a specific
model id even if it wanted to. On top of that, the Azure adapter shipped
only 2 hand-typed voices in voices/azure.json — the rest of Microsoft's
catalog was unreachable.

Fixed in one pass:

- Drop voices/*.json. Every getVoiceCatalog now calls unspeech REST
  (backend=microsoft|alibaba|volcengine). Azure proxies Microsoft's live
  voices/list; cosyvoice + volcengine use unspeech's embedded catalogs.
- Drop direct upstream provider calls from send(). All three adapters
  POST to <UNSPEECH_REST_BASE_URL>/v1/audio/speech with the openai-shaped
  body unspeech expects (model: `<backend>/<id>`). Azure SSML still built
  on our side so <prosody rate> speed survives — unspeech accepts
  pre-built <speak> documents.
- Fail-fast on every voices endpoint: empty ?model= → 400 MISSING_MODEL
  (no implicit DEFAULT_TTS_MODEL fallback), only `auto` resolves;
  streaming upstream missing → 503; unspeech non-2xx / network err → 502;
  malformed body → 502 with grepable message. No silent `{voices: []}`.
- /audio/models lists every LLM_ROUTER_CONFIG.tts.models key + `auto`.
- Frontend providerOfficialSpeech.listVoices passes ?model= and throws
  on upstream failure instead of returning [].
- New UNSPEECH_REST_BASE_URL configKV entry (no default, missing → 503).
  config-sync subscriber invalidates the voice cache when this key OR
  LLM_ROUTER_CONFIG changes.
- Router voice catalog Redis cache covers all providers with per-provider
  TTL (azure 6h live, alibaba/volcengine 24h since unspeech embeds them
  at build time).

Pending billing-SKU verification: DashScope cosyvoice now goes through
unspeech's WS-internal alibaba backend (was REST `/SpeechSynthesizer`).
Functional output equivalent — confirm bill after deploy, revert via
git history if WS pricing is materially higher.
2026-05-19 23:14:16 +08:00
RainbowBird 6b0788dd60 feat(server): expose streaming TTS model catalog from config
Streaming TTS model list was hardcoded in the official provider with two
Volcengine ids. This moves it server-side so operators control the
catalog without a client release.

Catalog lives on `STREAMING_TTS_UPSTREAM.models` (same configKV entry as
the ws upstream + key envelope) rather than a separate kv key — connection
target, keys, and surfaced ids are one deployment decision, splitting
them risks drift on rotation. `LLM_ROUTER_CONFIG.tts.models` is the
router/fallback domain for HTTP TTS; streaming is single-ws and has no
router semantics, so it gets its own `streamingTtsUpstreamSchema`
instead of reusing `ttsUpstreamSchema`.

New `GET /api/v1/audio/models/streaming` returns the configured list;
empty when upstream or models is unset (UI renders "no models" instead
of 5xx). Admin slice apply preserves existing `models` across key/connection
rotation so admin POSTs that only carry upstream+keys do not wipe the
catalog. Frontend `providerOfficialSpeechStreaming.listModels` fetches
the endpoint and throws on upstream errors (no silent empty array).
2026-05-19 23:14:16 +08:00
nyueki 4542a9d290 feat(stage-ui-spine): add Spine 2D runtime integration (#1810) 2026-05-19 19:13:35 +08:00
Nashchennc 8f1d3c6ab6 feat(core-agent): add chat orchestrator runtime (#1826) 2026-05-19 19:08:36 +08:00
DrHuangMHT cb9eacdd39 fix(live2d): encode filepaths in re-created model settings (#1838) 2026-05-19 19:08:15 +08:00
Neko 6b31552a16 fix(stage-ui): normalize spark:command tool schema (#1845) 2026-05-19 19:07:29 +08:00
Iro c04f4773c5 ref(server-*): refactor and cleanup server stuffs (#1833) 2026-05-19 14:42:23 +08:00
DrHuangMHT c2bf73c95d fix(stage-*): follow-up fix for #1696 (#1809) 2026-05-19 13:54:41 +08:00
github-actions[bot]andCrowdin Bot 82b0d6a80c chore(i18n): update translations (#1831)
This PR contains updated translations from Crowdin. Created from [GitHub
Actions](https://github.com/moeru-ai/airi/blob/main/.github/workflows/crowdin-cron-sync.yml).

You can review the source of translations
[here](https://crowdin.com/project/proj-airi)

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-05-19 00:08:29 +08:00
RainbowBird 201beae5ac fix(server): import 2026-05-18 23:48:11 +08:00
RainbowBird 45fb765df7 fix(server): ws conn 401 2026-05-18 23:36:08 +08:00
RainbowBird efe0f8ac19 refactor(server): streaming tts support model switch 2026-05-18 23:35:38 +08:00
RainbowBird 2854e0accc fix(server): tts streaming issue 2026-05-18 23:35:37 +08:00
RainbowBird ba9247fb47 feat(server,stage-ui): bidirectional streaming TTS + audio path refactor
Why:
- Add a real bidirectional streaming TTS path: raw LLM tokens are
  forwarded to the upstream model (Volcengine v3 via the unspeech ws
  bridge) without client-side segmentation, so the model owns sentence
  splitting and audio chunks play as they arrive.
- Move audio endpoints out of /api/v1/openai/. `/audio/voices`,
  `/audio/models`, `/audio/voices/streaming` are not real OpenAI public
  APIs, and the streaming TTS surface has nothing to do with OpenAI —
  keeping them under /openai/ mislabelled the contract.
- Introduce `capabilities.speech.transport` on ProviderDefinition so
  future streaming providers (ElevenLabs / Cartesia / OpenAI Realtime)
  opt in without touching Stage.vue or the session factory.
- Unify Stage.vue's TTS path through a single StageTtsSession so the
  chat-orchestrator hooks no longer branch on provider id.

What:
- apps/server: new ws proxy /api/v1/audio/speech/ws bridges client ↔
  unspeech with auth, pre-flight flux check, billing from upstream
  session.finished.usage, OTel spans.
- apps/server: audio routes moved from /api/v1/openai/audio/* to
  /api/v1/audio/* (hard cutover; 404 sentinel tests added).
- apps/server: new /api/v1/audio/voices/streaming proxy reads voices
  from unspeech /api/voices?provider=volcengine.
- apps/server: new STREAMING_TTS_UPSTREAM configKV entry +
  scripts/seed-streaming-tts.ts.
- stage-ui: new libs/speech/streaming-pipeline.ts opens one ws per LLM
  intent (appendText / finish / cancel + onSentence / onError / onDone).
- stage-ui: new libs/speech/tts-session.ts — StageTtsSession interface
  with segmenter and streaming adapters; factory dispatches by
  capabilities.speech.transport instead of hard-coded provider id.
- stage-ui: providerOfficialSpeechStreaming with capabilities.speech =
  { transport: 'bidirectional-ws' }; settings page with model/voice
  picker + ws-based preview.
- stage-ui: Stage.vue chat hooks collapsed to a single currentSession;
  hot-swap watcher cancels mid-session on provider/voice/model change;
  unmount cancels and drains playback.

Tests:
- 9 streaming-pipeline tests (happy path / buffered / error / cancel /
  truncation)
- 11 tts-session tests (factory branch coverage + adapter contracts)
- 4 audio-speech-ws route tests (forwarding / billing / pre-flight /
  config-missing)
- 3 legacy-path 404 sentinels in v1 route tests
- Verification doc updated to reflect automated coverage.
2026-05-18 23:34:35 +08:00
RainbowBird bf1aba757c feat(server): stream tts provider 2026-05-18 23:33:24 +08:00
RainbowBird af17e9cbc2 feat(server): llm & tts gateway (#1837) 2026-05-18 23:31:07 +08:00
RainbowBird 31376fc6f1 feat(server, stage-ui): metrics 2026-05-18 23:29:14 +08:00
RainbowBird 982da671ef fix(server): ws conn 401 2026-05-18 17:05:49 +08:00
Neko Ayaka f33d485b82 feat(stage-ui): io tracer for CALL tokens 2026-05-18 01:23:14 +08:00
Neko Ayaka 77eeb64f51 fix(stage-ui): ensure started 2026-05-18 01:22:32 +08:00
Neko Ayaka 4622b99e2a refactor(pipelines-audio): better token processing pipeline, ACT, DELAY, CALL, unified 2026-05-18 01:20:21 +08:00
Neko Ayaka c459e647d0 fix(stage-ui,stage-tamagotchi): minor animation fix, and caption auto fade out 2026-05-17 18:37:36 +08:00
RainbowBird b4360c1090 fix(server): update token retrieval for WebSocket client to ensure reactive updates 2026-05-17 13:43:19 +08:00
Neko Ayaka bc69df548e feat(plugin-*): prompt for toolset 2026-05-15 18:13:31 +08:00
RainbowBird 3984677b01 feat(analytics): integrate PostHog for server-side event tracking
- Added a new PostHog client for capturing server-side business events such as Stripe webhooks and subscription state changes.
- Implemented various tracking functions for pricing funnel steps, character creation, and chat session starts.
- Enhanced the flux meter tests to handle partial charges and report unbilled flux correctly.
- Updated the CharacterDialog and Flux settings pages to track user interactions with analytics events.
- Introduced a mechanism to identify users on PostHog based on authentication state to ensure accurate funnel tracking.
- Added necessary dependencies for PostHog integration in the project.
2026-05-15 16:20:47 +08:00
Lilia_Chenandautofix-ci[bot] bc7dda3d5f feat(stage-tamagotchi): add experimental Godot stage sidecar (#1830)
## Summary

Adds the experimental Godot stage sidecar path for `stage-tamagotchi`.

This PR wires the existing Tamagotchi model selection flow into an
external Godot runtime window. The renderer gates Godot scene input to
VRM models, Electron main materialises the selected model bytes to a
local file, and the Godot sidecar receives the native path over a local
WebSocket bridge before importing and displaying the avatar at runtime.

## What Changed

- Added a typed Godot scene input contract with `format: "vrm"`.
- Added renderer-side VRM-only gating before sending selected model data
to Electron main.
- Added Electron main sidecar management for:
  - launching Godot
  - starting the local WebSocket bridge
  - materialising selected VRM bytes under app `userData`
  - forwarding scene apply messages to Godot
  - optional remote debugging support
- Added Godot runtime scripts for:
  - sidecar startup and WebSocket orchestration
  - message envelope parsing
  - avatar import and atomic replacement
  - runtime VRM import through Godot `GLTFDocument`
- Added engine-local docs for runtime import, live debugging, vendor
patches, and current VRM support boundaries.
- Removed temporary tests after using them to verify the glue behaviour
locally, to keep the review surface smaller.

## Vendor Code Note

A large part of this PR is vendored Godot add-on code, not AIRI business
logic.

The bulk of the added files under:

- `engines/stage-tamagotchi-godot/addons/vrm/**`
- `engines/stage-tamagotchi-godot/addons/Godot-MToon-Shader/**`

comes from V-Sekai Godot VRM / MToon add-ons. These files are required
because Godot plugins are project-local source/assets rather than
package-manager dependencies.

The intended review scope for vendor code is limited to:

- source baseline metadata
- license/plugin config
- Godot-generated metadata notes
- the documented local patch in `addons/vrm/vrm_extension.gd`

The application/runtime code to review is mainly under:

- `apps/stage-tamagotchi/src/shared/eventa/index.ts`
- `apps/stage-tamagotchi/src/renderer/pages/settings/models/`
- `apps/stage-tamagotchi/src/main/services/airi/godot-stage/`
- `engines/stage-tamagotchi-godot/scripts/`

## Current Boundary

This is still an experimental G1 Godot sidecar path.

The runtime scene input contract accepts `.vrm` files only. The current
Godot runtime importer covers the VRM 0.x path used by the local fixture
through AIRI’s runtime bridge over the vendored VRM extension. VRM 1.0
editor import support exists in the vendored add-on, but the sidecar
runtime importer does not yet register the full `VRMC_*` extension set,
so this PR does not claim full VRM 1.0 runtime support.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-05-15 14:37:32 +08:00
RainbowBird eada7e8c4e chore: update @moeru/eventa to version 1.0.0-beta.5 in pnpm-workspace.yaml 2026-05-15 02:51:23 +08:00
Neko 541b9fa53c fix(server-runtime): ignore duplicate websocket listener (#1829) 2026-05-14 01:53:41 +08:00
ArkandNeko a161badad8 feat(stage-ui): add copy feedback to chat action menu (#1689)
---------

Co-authored-by: Neko <neko@ayaka.moe>
Co-authored-by-agent: Unknown <unknown@example.com>
2026-05-13 12:39:44 +08:00
Asish Kumar cb30e41dc6 fix(stage-tamagotchi): shorten websocket status tooltip (#1822) 2026-05-13 12:11:13 +08:00
felix tremblayandautofix-ci[bot] 7b7fb0f238 fix(stage-ui-live2d): prevent motions from overriding lip sync mouth values (#1783)
---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by-agent: Unknown <unknown@example.com>
2026-05-13 12:10:03 +08:00
LiaoZiqi-GZFLS 0086eee9d6 fix(stage-tamagotchi): language persistence electron fix for #1658 (#1812) 2026-05-13 12:07:25 +08:00
Doji 2c432fc1c8 refactor(stage-web,stage-ui): replace warpdrive plugin with unplugin-basemove (#1818) 2026-05-13 12:03:30 +08:00
Nashchennc e882ba7dd6 feat(core-agent): harden registry buckets and bridge ingest isolation (#1819) 2026-05-13 12:02:35 +08:00
github-actions[bot]andCrowdin Bot 3b3c5f6aaf chore(i18n): update translations (#1813)
This PR contains updated translations from Crowdin. Created from [GitHub
Actions](https://github.com/moeru-ai/airi/blob/main/.github/workflows/crowdin-cron-sync.yml).

You can review the source of translations
[here](https://crowdin.com/project/proj-airi)

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-05-12 23:13:33 +08:00
Makitoandautofix-ci[bot] d02a76f944 feat(stage-tamagotchi,stage-shared): wire up global shortcut service and devtools (#1811)
1. Introduce the global shortcut service
1. Add more concrete failure reasons for shortcut registration attempts
1. Add a devtool page to test (un) registering and triggering shortcuts

--- 

<img width="1174" height="921" alt="Screenshot 2026-05-10 at 19 33 45"
src="https://github.com/user-attachments/assets/10712013-fd49-4285-bdc9-4e6955d9c3a7"
/>

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-05-10 20:38:47 +09:00
Ryan Leiandleiyutian 37807b84d6 fix(ui): add openOnClick prop to Combobox for reliable dropdown opening (#1795)
---------

Co-authored-by: leiyutian <leiyutian@echo.tech>
Co-authored-by-agent: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 22:44:27 +08:00
github-actions[bot]andCrowdin Bot 24cc7a3e12 chore(i18n): update translations (#1799)
This PR contains updated translations from Crowdin. Created from [GitHub
Actions](https://github.com/moeru-ai/airi/blob/main/.github/workflows/crowdin-cron-sync.yml).

You can review the source of translations
[here](https://crowdin.com/project/proj-airi)

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-05-09 20:08:32 +08:00
DrHuangMHT 24da875aa6 refactor(stage-*): improve transcription UX and DX (#1685) 2026-05-09 19:09:39 +08:00
Neko Ayaka 7bc3781ee2 fix(stage-tamagotchi): missing bridge for spark:notify 2026-05-09 03:42:45 +08:00
RainbowBird 9d2d43855c refactor(chat): update datetime prefixing logic for user messages and improve formatting 2026-05-09 00:38:50 +08:00
RainbowBird 54b0af0a08 chore(stage-pages): resolve type 2026-05-08 21:34:11 +08:00
RainbowBird 99956014fa feat(server): admin api (#1788) 2026-05-08 21:14:00 +08:00
RainbowBird d0e2b450cd feat(stage-ui): chat sync (#1775) 2026-05-08 21:14:00 +08:00
RainbowBird 9d6d99192c feat(auth): enhance token refresh handling and clear auth state on errors 2026-05-08 21:14:00 +08:00
Neko Ayaka 13566667e1 fix(stage-ui): error item should fit content width, reasoing should not have pt 2026-05-08 21:10:32 +08:00
hahaqwq 4ecd51076d fix(stage-pocket,stage-server): correct Android deep link scheme (#1794) 2026-05-08 20:48:55 +08:00