Commit Graph
3816 Commits
Author SHA1 Message Date
Lilia_Chen 6a61248cd4 refactor(stage-tamagotchi-godot): move to engines dir (#1715) 2026-04-23 19:30:53 +08:00
0xSelenicDove ad7cf632ed chore(docs): add missing tamagotchi setup-and-use page to sidebar (#1713) 2026-04-23 18:42:18 +08:00
Neko Ayaka 20a515e169 chore(ci): added Godot vscode extension recommendation, and .prototools for managing dotnet versions 2026-04-23 02:19:44 +08:00
chaosreloadandautofix-ci[bot] a189536489 feat(providers): add Amazon Bedrock provider (#1256)
## Summary

Add support for Amazon Bedrock as an LLM provider using the native
**Converse API** with API Key authentication.

## Motivation

AWS Bedrock provides access to frontier models (Claude, Amazon Nova,
Llama, DeepSeek etc.) with enterprise-grade security and compliance.
Many teams running AI workloads on AWS infrastructure want to use
Bedrock directly, keeping all traffic within the AWS network.

## Implementation

- Uses Amazon Bedrock's native **Converse API**
(`bedrock-runtime.{region}.amazonaws.com/model/{modelId}/converse`)
- Authentication via **Amazon Bedrock API Key** (`Authorization: Bearer
<key>`) — no SigV4 signing, no extra dependencies
- Config: `apiKey` (Bedrock API key) + `region` (AWS region, default:
`us-east-1`)
- All Bedrock-specific config is declared via the generic
`onboardingFields` mechanism on the provider definition — no
`isAmazonBedrock` branching, no `ProviderConfigData` type changes
- Dynamic model listing via `ListFoundationModels` +
`ListInferenceProfiles` APIs, with fallback to a static list
- Streaming: calls `/converse` (standard JSON response), then re-emits
the full text as `text/event-stream` character-by-character —
bearer-token auth does not support the binary AWS Event Stream protocol
required by `/converse-stream`

## Supported Models

**Anthropic Claude (via Bedrock)**
- Claude Opus/Sonnet/Haiku 4.x
- Claude Sonnet 3.7 (hybrid reasoning)
- Claude Sonnet 3.5 v2

**Amazon Nova**
- Nova Pro (multimodal)
- Nova Lite (multimodal, low cost)
- Nova Micro (text-only, lowest cost)

**Meta / Others**
- Llama 3.3 70B Instruct
- DeepSeek, Moonshot, Minimax models available via inference profiles

## Authentication

Generate a Bedrock API key in: **AWS Console → Amazon Bedrock → API
Keys**

> Note: Long-term API keys have a 30-day expiry. AWS recommends them for
development/exploration use.

## Notes

⚠️ **CORS in browser**: Like other providers (Anthropic, etc.), direct
browser calls to Bedrock are subject to CORS restrictions. Works out of
the box in Tauri desktop app and Node.js server environments. For
browser use, a CORS proxy is needed.

## Testing

```
pnpm vitest run packages/stage-ui/src/libs/providers/providers/amazon-bedrock/index.test.ts
```

---------
Co-authored-by-agent: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-04-22 17:37:29 +00:00
Neko Ayaka 762fd017b0 chore(.agents/skills): added agent-browser-electron for better self-verification 2026-04-23 01:09:46 +08:00
Neko Ayaka a3249ccd68 feat(stage-tamagotchi,stage-ui,ui): input should not flink, added retry for errored item, adjusted button 2026-04-23 01:09:46 +08:00
Neko Ayaka ee86608195 fix(stage-ui): overflow chat bubble 2026-04-23 01:09:45 +08:00
567fd6666e feat(stage-tamagotchi-godot): initiation of Godot stage (#1697)
## Description

This PR introduces `@proj-airi/stage-tamagotchi-godot` as the initial
Godot C# workspace package for the desktop-only `stage-tamagotchi` stage
runtime track.

The current scope is intentionally limited to G0 bootstrap work:
- add the Godot/.NET project files and workspace wrapper files
- establish the package boundary for the Godot-backed desktop stage
runtime
- add a minimal runnable scene and script so the Godot project can be
opened, built, and executed inside the repo

Concretely, this PR adds:
- the new `packages/stage-tamagotchi-godot` package
- Godot project files (`project.godot`, `.csproj`, `.sln`, editor/config
files)
- a minimal `stage-root` scene and `StageRoot.cs` script
- basic visible scene contents for runtime validation (`Camera3D`,
`OmniLight3D`, `Box`)
- a package README describing scope and ownership boundaries
- minimal package scripts for build/typecheck via `dotnet build`

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: LemonNeko <self@lemonneko.moe>
Co-authored-by: Garfield Lee <Garfield550@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Neko <neko@ayaka.moe>
2026-04-23 01:04:01 +08:00
0xSelenicDove c259cec35f feat(pipelines-audio): Universal Speech Transformer port with CJK & keep-text support (#1702) 2026-04-22 02:48:41 -07:00
Neko Ayaka 94031bf1c4 fix(stage-ui,ui): histoire wasn't configured correctly 2026-04-22 16:57:35 +08:00
Neko Ayaka ca4c99f074 fix(stage-pages,stage-ui): plugin host update 2026-04-22 14:23:45 +08:00
Neko Ayaka c7cf0c6a47 fix(stage-pages,stage-shared,stage-ui): rollback 3f82942 falsy fix 2026-04-22 14:14:02 +08:00
DrHuangMHT 32d2ebfe73 fix(stage-ui): use duckdb singleton to prevent memory leak (#1679) 2026-04-22 14:03:57 +08:00
Iro 3f829421d3 fix(server-runtime): enforce auth & routing safety, fix lifecycle leaks (#1686) 2026-04-22 14:03:16 +08:00
Lulu e165829b19 fix(server): trust https localhost and loopback for mkcert Vite dev (#1691) 2026-04-22 14:02:20 +08:00
22b0d27001 fix(stage-tamagotchi): hide chat input scrollbar when content fits (#1687)
---------

Co-authored-by: octo-patch <octo-patch@github.com>
Co-authored-by: ximi-helper <ximi-helper@octo-patch.com>
2026-04-22 14:00:12 +08:00
Neko Ayaka 36ee517e1e chore(README.md): updated for more instructions 2026-04-22 13:54:02 +08:00
Neko Ayaka 8603d8cd7a fix(stage-tamagotchi): fix test 2026-04-22 13:52:40 +08:00
Neko Ayaka 509c00d9a5 feat(plugin-sdk,stage-tamagotchi): rework of plugin structure, integrated kits api, now plugin manifest is plugin.airi.json 2026-04-22 13:52:11 +08:00
Neko Ayaka ea2b30e2b8 fix(stage-ui): outdated for mcp.ts 2026-04-22 03:37:58 +08:00
Neko Ayaka 5bbf9559a4 refactor(stage-ui,stage-tamagotchi): have plugin-tools, mcp-tools to register directly to llm.ts 2026-04-22 03:34:40 +08:00
DrHuangMHT 7e4486c068 chore(ci): fix typecheck on navigator.gpu (#1700) 2026-04-21 20:27:17 +08:00
Neko Ayaka 3390122085 feat(plugin-sdk-tamagotchi,airi-plugin-game-chess): tools api, gamelet api, init chess gamelet 2026-04-21 17:17:20 +08:00
Neko Ayaka 0294dad6ef feat(plugin-sdk): kits api, binding api, and better comments 2026-04-21 16:46:04 +08:00
Neko Ayaka a406ffb67c feat(stage-tamagotchi): widget now supports customizable ui from plugin/extension 2026-04-21 02:23:34 +08:00
Neko Ayaka 033e76c2f1 feat(stage-tamagotchi): built-in local loopback http server 2026-04-20 20:39:12 +08:00
Neko Ayaka 60456c7567 fix(ui): SelectTab size issue 2026-04-18 19:27:02 +08:00
Neko Ayaka d2d5493136 fix(stage-tamagotchi): concurrent apply and auto-heal will have conflicts 2026-04-18 19:26:22 +08:00
Neko Ayaka 2ab21879dd chore(deps): bump dependencies 2026-04-18 19:18:17 +08:00
Luluandautofix-ci[bot] a40cbd67cf fix(stage-layouts): mount LoginDrawer in settings layout on mobile (#1675)
---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by-agent: Cursor <unknown@example.com>
2026-04-18 18:26:19 +08:00
github-actions[bot]andCrowdin Bot 2a444245ae chore(i18n): update translations (#1678)
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-04-18 18:20:48 +08:00
Neko Ayaka 70495439ad refactor(core-agent,stage-ui): move spark-notify agent to core-agent 2026-04-17 16:18:42 +08:00
github-actions[bot]andCrowdin Bot 8d6905481b chore(i18n): update translations (#1672)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-17 15:09:06 +08:00
github-actions[bot] 7bc43bd986 chore: update README release artifacts to v0.9.0 2026-04-16 19:04:54 +00:00
RainbowBird bef1598179 fix(stage-ui): refresh token concurrency 2026-04-17 02:59:14 +08:00
RainbowBird 8967bbe211 feat(server): add TTS support with per-character billing 2026-04-17 02:59:14 +08:00
RainbowBird 57533044f7 feat(server): add gateway and model configuration to environment variables 2026-04-17 02:59:14 +08:00
RainbowBird a11727020a feat(server/billing): implement debt ledger for TTS service using FluxMeter 2026-04-17 02:59:14 +08:00
Neko Ayaka 1258c246d5 chore: updated 2026-04-16 23:21:45 +08:00
autofix-ci[bot] 25aec906dc [autofix.ci] apply automated fixes 2026-04-16 22:58:10 +08:00
Nekoandgemini-code-assist[bot] 9b4ef8862b Apply suggestion from @gemini-code-assist[bot]
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-04-16 22:58:10 +08:00
Jensen Huang c14e9547d9 feat(stage-tamagotchi): improve updater cleanup lane and admin diagnostics 2026-04-16 22:58:10 +08:00
Jensen Huang 1a11409b1e fix(stage-tamagotchi): use electron cache path for updater cleanup 2026-04-16 22:58:09 +08:00
autofix-ci[bot] c4a2e88a58 [autofix.ci] apply automated fixes 2026-04-16 22:58:06 +08:00
Jensen Huang 026168044e fix(stage-tamagotchi): updater regressions, downgrade warnings, and cross-platform cache cleanup
- Fixed architecture-sensitive updater tests (26/26 passing)
- Added downgrade-warning UI via semver comparison
- Restored Windows custom log path and implemented cross-platform cache cleanup
- Made updater diagnostics always-on (no gating)
2026-04-16 22:55:54 +08:00
Neko Ayaka 499617e436 fix(stage-tamagotchi): chat sync broken for cross window 2026-04-16 16:58:31 +08:00
github-actions[bot] e10b3376d4 chore(nix): update pnpmDeps hash 2026-04-16 08:15:40 +00:00
NJX 5187572c42 fix(stage-ui/inference): correctness and resilience fixes for browser-side inference infra (#1663)
## Summary

Addresses **Phase 1** of the inference infrastructure roadmap (#1661).
Six correctness and resilience issues fixed across adapters, workers,
and the unified protocol layer.

**Scope:** `packages/stage-ui/src/libs/inference/`,
`packages/stage-ui/src/libs/workers/`, `packages/stage-ui/src/workers/`

---

## Problems & Motivation

### 1. Kokoro Singleton cannot recover from terminal state

`getKokoroAdapter()` creates a singleton that is never reset. Once the
adapter reaches `terminated` or `error` (restarts exhausted), the
singleton is permanently dead -- users must refresh the page.

**Root cause:** `globalAdapter` is only re-created when `null`, never
checks the state of the existing instance. `scheduleRestart()` silently
returns when retries are exhausted, leaving state stuck at `'error'`
instead of transitioning to `'terminated'`.

**Fix:**
- `getKokoroAdapter()` now detects `terminated` / `error` states and
re-creates the adapter automatically
- `scheduleRestart()` in both Kokoro and Whisper adapters transitions to
`'terminated'` when max restarts are exhausted, making the dead state
detectable

### 2. `voices!` non-null assertion after nullable assignment

`kokoro.ts:275` assigns `voices = (response.metadata?.voices as Voices)
?? null` (can be null), but L288 returns `voices!` -- if the worker
returns unexpected metadata, callers receive `null` but the type system
promises `Voices`, causing downstream crashes.

**Fix:** Replaced with explicit null check + throw, routing into the
existing error recovery path.

### 3. Whisper Worker silently drops concurrent requests

The worker's `runInference()` has `if (processing) return` which
silently drops the request. The adapter's `waitForMessage()` never
receives a response, causing the Promise to hang for 120 seconds until
timeout.

**Root cause:** The bare boolean is safe in a single-threaded worker --
the real bug is the silent `return` with no error response.

**Fix:** Replaced with `sendError(requestId, ...)` so the adapter
receives an immediate rejection.

### 4. Whisper adapter leaks event listeners on worker restart

`ensureWorker()` attaches anonymous `message` and `error` listeners each
time a new Worker is created. `destroyWorker()` only calls
`worker.terminate()` without removing listeners. On restart paths
(`scheduleRestart -> ensureWorker`), old Worker listener closures may
prevent GC.

**Impact:** Whisper is most critical (2 listeners + restart logic).
Kokoro and Background Removal have the same pattern but lower risk.

**Fix:** All 3 adapters now store listener references and call
`removeEventListener` before `terminate()`. Whisper's
`terminateAdapter()` routes through `destroyWorker()` instead of direct
`worker.terminate()`.

### 5. Error classification is incomplete

`classifyError()` only matches 3 string patterns (OOM, DEVICE_LOST,
TIMEOUT). `LOAD_FAILED` and `INFERENCE_FAILED` are defined in the
`InferenceErrorCode` type but never produced. All workers hardcode
`recoverable: false`.

**Fix:**
- `classifyError(error, phase?)` gains a `phase` parameter: specific
patterns (OOM etc.) take priority, unmatched errors fall through to
`LOAD_FAILED` / `INFERENCE_FAILED` based on phase
- New `isRecoverable(code)` helper: TIMEOUT and DEVICE_LOST are
recoverable
- All 3 workers' `sendError()` updated to pass phase and use dynamic
recoverability

### 6. No dtype/device fallback chain

Kokoro Worker attempts model loading once with the requested dtype;
failure is terminal. Whisper Worker hardcodes `encoder_model: 'fp16'`
which crashes on devices that don't support it.

**Fix:**
- **Kokoro Worker:** New `DTYPE_FALLBACK` and `DEVICE_FALLBACK` maps.
Tries `fp16 -> fp32 -> q8 -> q4` on the same device, then `webgpu ->
wasm` device fallback. Reports `actualDtype` and `actualDevice` in
`ModelReadyResponse.metadata`
- **Whisper Worker:** Wraps fp16 encoder load in try-catch; falls back
to fp32

---

## State after changes

| Component | Before | After |
|-----------|--------|-------|
| Kokoro singleton | Returns dead instance forever after terminal error
| Auto-detects and re-creates |
| `voices` return | `voices!` can return null, lying to type system |
Explicit throw, enters error recovery path |
| Whisper Worker concurrency | Silent drop, Promise hangs 120s |
Immediate error response |
| Event listeners | Anonymous, never cleaned up | Stored references,
removeEventListener on destroy |
| Error classification | 4/6 codes reachable, recoverable hardcoded
false | 6/6 codes reachable, dynamic recoverability |
| dtype loading | Single attempt, failure is terminal | Progressive
fallback chain, reports actual config used |

---

## Files changed

| File | Changes |
|------|---------|
| `libs/inference/protocol.ts` | `classifyError` phase param, new
`isRecoverable` helper |
| `libs/inference/protocol.test.ts` | **New** -- 14 tests for
classification and recoverability |
| `libs/workers/worker.ts` | Silent drop fix, sendError phase, fp16
fallback |
| `workers/kokoro/worker.ts` | sendError phase, dtype/device fallback
chain |
| `workers/background-removal/worker.ts` | sendError phase |
| `libs/inference/adapters/whisper.ts` | Listener cleanup,
terminateAdapter uses destroyWorker, scheduleRestart terminal state |
| `libs/inference/adapters/kokoro.ts` | Singleton recovery, voices
assertion fix, listener cleanup, scheduleRestart terminal state |
| `libs/inference/adapters/kokoro.test.ts` | **New** -- 5 tests for
singleton and state transitions |
| `libs/inference/adapters/background-removal.ts` | Listener cleanup,
extracted destroyWorker |

## Test plan

- [x] `pnpm exec vitest run packages/stage-ui/src/libs/inference/` --
30/30 tests pass (protocol, kokoro adapter, GPU coordinator, load queue)
- [x] `pnpm -F @proj-airi/stage-ui typecheck` -- clean
- [x] `npx eslint` on all 9 changed files -- clean
- [x] Pre-commit hooks pass

Co-authored-by-agent: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 16:11:05 +08:00
Nashchenncandautofix-ci[bot] bf41655dbb feat(core-agent): extract pure runtime logic from stage-ui into core-agent (#1524)
Depends on #1487 

## Summary

- Introduce `packages/core-agent` — a new pure-runtime package that
extracts zero-Vue/Pinia algorithmic logic from `@proj-airi/stage-ui`,
following a "compatible facade + core sinking" strategy
- Migrate shared chat types, LLM streaming types, chat hook registry,
session message merge logic, context registry algorithm, and LLM service
utilities into `core-agent`
- `stage-ui` files are preserved as re-exports / thin wrappers — all
external imports, store IDs, and public APIs remain unchanged

## Motivation

`stage-ui` currently mixes pure agent runtime logic (algorithms, type
definitions, stateless utilities) with Vue/Pinia state management and
browser-specific adapters. This coupling makes it hard to:
- Test agent logic in isolation
- Reuse agent algorithms outside of Vue contexts (e.g., server-side,
CLI, other frameworks)
- Reason about the boundary between "what the agent does" vs "how the UI
manages state"

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by-agent: Unknown <unknown@example.com>
2026-04-16 16:09:22 +08:00
Octopus 11ac511dd9 feat(stage-ui,i18n): add MiniMax Speech TTS provider (#1594)
## Summary

- Add `minimax-speech` TTS provider using MiniMax's T2A v2 API
- Implement streaming SSE response with hex-encoded audio decoding (no
external dependency required)
- Include a curated static voice list (English and Mandarin voices)
- Add `speech-2.8-hd` (default) and `speech-2.8-turbo` model entries
- Support configurable base URL defaulting to `https://api.minimax.io`
- Add i18n translations for all 9 supported locales

Closes #1274

## Implementation Details

The provider uses a custom `fetch` interceptor within the
`SpeechProvider` interface to:
1. Parse the incoming OpenAI-style request (`input`, `voice`, `model`)
2. Call MiniMax's `/v1/t2a_v2` SSE streaming endpoint
3. Decode hex-encoded audio chunks from SSE events (skipping the summary
chunk with `status=2`)
4. Return a concatenated `audio/mpeg` response

## API Reference

- TTS: https://platform.minimax.io/docs/api-reference/speech-t2a-http
2026-04-16 16:07:30 +08:00