Support multiple API keys per provider with random selection for load
balancing. When AI_MODELS_CONFIG has multiple apiKeyEnv values for
a provider, requests will randomly select one available key.
- Update schema to accept apiKeyEnv as string or string array
- Add random key selection in resolveApiKey()
- Update validation to check at least one key exists
- Add tests for array format support
* fix: enable image support for Kimi K2.5 model
Kimi K2.5 supports image input but was incorrectly blocked by the
supportsImageInput check that excluded all Kimi models without
"vision" in the name. Updated the condition to only exclude the
older K2 model while allowing K2.5.
* fix: improve Kimi K2.5 image support logic and add tests
- Only block kimi-k2 specifically, not all Kimi models
- Add unit test for kimi-k2.5 image support
Replaces the hardcoded API endpoint with a function that retrieves
the correct base path for server model requests. Improves compatibility
with deployments where the API is not served from the root path.
Enables ref forwarding for improved integration with parent components
and libraries that require direct DOM access. Enhances flexibility and
maintainability by switching to a forwardRef implementation.
Previously, Ollama only used the OLLAMA_BASE_URL environment variable.
Now client-provided base URL from settings takes priority, allowing
users to configure custom Ollama endpoints (e.g., remote servers).
Fixes#652
Allows users to select Ollama as a provider from client settings.
Previously, Ollama was blocked with "Invalid provider" error even
though the UI supported it.
Fixes#652
Ollama is a local/self-hosted model that doesn't require API keys.
The SSRF protection was incorrectly blocking Ollama connections
when users provided a custom base URL without an API key.
Fixes#652
Add full Traditional Chinese support for Hong Kong/Taiwan users by
creating a zh-Hant dictionary and registering the locale across the
web app, metadata, and Electron desktop menu system.
The previous logic only restored on iframe ready, but chartXML might
be set AFTER the iframe is ready (session loaded after iframe).
Now we track the last restored XML and load whenever chartXML changes
to a new real diagram while iframe is ready.
Fixes diagram not restoring after refresh. The issue was:
1. DrawIoEmbed rendered with canPersist=false
2. Session restore loaded diagram into iframe
3. canPersist changed to true, causing iframe remount
4. New iframe loaded empty, losing the diagram
Now we wait for isIndexedDBUsable() to complete before rendering,
avoiding the remount entirely.
Address review comments: canPersist is set async after mount, so DrawIoEmbed
needs to remount when it resolves to apply correct configuration and URL params.
- Enable draw.io autosave and handle autosave events to update chartXML
- Clear modified state after autosave to avoid beforeunload prompts
- Disable confirmExit in draw.io configuration
- Set modified=false and keepmodified=false URL parameters
- Fix session save condition to also save when only diagram exists
- Fix: Do not close shared IndexedDB connection in isIndexedDBUsable()
This reverts commit e7c29fb410.
The PR introduced an IndexedDB error: 'Failed to execute transaction on IDBDatabase: The database connection is closing.'
* fix(electron): prevent beforeunload prompt by using autosave
- Enable draw.io autosave and handle autosave events to update chartXML
- Clear modified state after autosave to avoid beforeunload prompts
- Disable confirmExit in draw.io configuration
- Set modified=false and keepmodified=false URL parameters
- Fix session save condition to also save when only diagram exists
* fix: persist diagram-only saves and ref typing
* fix: harden persistence checks and export timeout
* feat(prompt): add language-aware response rules with english fallback
Added language handling rules for user interactions.
* refactor(prompt): simplify language matching instruction
* feat(electron): bundle draw.io for offline support
- Download draw.io static files during CI build (v29.3.5)
- Detect Electron and use local draw.io files instead of CDN
- Add offline=1 parameter to disable external service calls
- Skip /drawio path from i18n middleware redirect
- Add public/drawio/ to .gitignore (downloaded during build)
This allows the Electron app to work completely offline.
* chore: bump version to 0.4.12-beta.3 for offline test
* fix(electron): ad-hoc sign macOS app for bundled draw.io compatibility
* chore: bump version to 0.4.12-beta.4 for ad-hoc sign test
* fix(electron): disable electron-builder signing to use custom ad-hoc signing
* chore: bump version to 0.4.12-beta.5
* feat(mcp): update UI with project logo and modern dialog styles
- Replace Next.js logo with project favicon-white.svg
- Modernize modal dialogs with backdrop blur, animations, and DM Sans font
- Update button styles to match header design
- Change title to "Next AI Draw.io"
- Rename "Save" to "Download" for clarity
- Bump version to 0.1.15
* chore: remove dead code (unused download helpers and pendingManualSave)
Fixes#633 - browser showing infinite loading spinner when accessing
the MCP server URL without the session parameter.
When users access http://localhost:6002 directly (without ?mcp=xxx),
the page now auto-redirects to the most recent active session instead
of showing "No session" with an infinite loading spinner.