- Add background job that checks model availability every 5 hours
- Automatically removes unavailable models from fallback chain
- Adds unavailable models section in admin UI with blur styling
- Allows admins to re-add models when they become available again
- Extends model schema with available, lastChecked, unavailableSince fields
- Adds API endpoints: GET /api/admin/models/availability, POST /api/admin/models/:id/readd
- Add cerebras and chutes to server-side PLANNING_PROVIDERS to match client
- Add optional chaining to rate limit form inputs to prevent null reference errors
Public models are now display-only and don't require a Model ID:
- Removed Model ID input field from admin.html public models section
- Updated admin.js to not require or send Model ID for public models
- Updated server API to accept public models without Model ID
- Uses display label as the identifier for public models
- Only requires Model ID for OpenCode models (which need it for execution)
Public models are purely for user-facing display in the builder dropdown,
while OpenCode models form the actual execution fallback chain.
- Never use public model ID in opencode fallback chain
The opencode model selection is now independent of public models,
always using the opencodeModels array in order for fallback chain.
- Add zero output detection to trigger fallback
When a model returns empty output, it now triggers fallback to the
next model in the chain instead of returning empty results.
Fixes issues where:
1. Generic 'opencode' model ID from public models caused failures
2. Empty responses didn't trigger fallback to backup models
Users now use OpenCode Models (Fallback Chain) for model selection.
- Removed Auto Model for Hobby/Free Plan section from admin panel
- Removed OpenCode Ultimate Backup Model section from admin panel
- Updated server to use opencodeModels for free plan users
- Removed backup model fallback logic (opencodeModels chain handles this)
- Add OpenCode Models section with dropdown selection from available models
- Add Public Models section with manual model ID input
- Both sections have up/down ordering buttons for fallback chain priority
- OpenCode models used for execution fallback when rate limits/errors occur
- Public models displayed in builder dropdown for user selection
- Remove unified provider chain in favor of two separate lists
- Keep all existing functionality: Auto Model, Provider Limits, Icon Library, etc.
Add full support for Kilo Gateway AI provider across the codebase:
- Add custom loader for 'kilo' provider in provider.ts with API key detection
- Add auth CLI hint for Kilo Gateway in auth.ts
- Add Kilo to DEFAULT_PROVIDER_SEEDS in chat server.js
- Add Kilo to PLANNING_PROVIDERS for planning chain support
- Add Kilo provider configuration with baseURL and API key support
- Update admin env config to show Kilo API key status
Kilo Gateway provides access to 500+ AI models through a single
OpenAI-compatible endpoint at https://api.kilo.ai/api/gateway
- Removed opencodeChain variable entirely
- Removed chain form/list from admin UI
- Fallback now uses the order of models in the OpenCode models list
- Updated buildOpencodeAttemptChain to iterate through opencodeModels
- Removed chain-related API endpoints
- Simplified to just two lists: opencodeModels and publicModels
- Simplified to 3 clear sections:
1. OpenCode Models: OpenCode dropdown + display name + order buttons
2. OpenCode Chain: Fallback chain with add form + order buttons
3. Public Models: Manual entry + order buttons (completely separate)
- New state variables: opencodeModels, opencodeChain, publicModels
- Clean API endpoints for chain operations
- Removed all confusing legacy code and naming
- Provider Models section: restored OpenCode integration with dropdown
- Public-Facing Models section: completely separate manual entry
- Provider Chain section: fallback chain with up/down buttons (unchanged)
- Added separate arrays: providerModels and publicModels
- Added reorder support for both provider and public models
- Updated server to handle providerModel type and reorder by type
- Add order number badge (#1, #2, #3) to each public model
- Add up/down arrow buttons to reorder models in the list
- Add persistPublicModelsOrder function to save reordered list
- Add server-side /api/admin/models/reorder endpoint
- Remove automatic alphabetical sorting to preserve custom order
- First model (#1) gets green background highlighting
Implements both Option A and B for admin token management:
- Option A (mode='remaining'): Set tokens remaining to use (calculates usage from limit)
- Option B (mode='usage'): Directly set tokens consumed
- Original mode='limit': Still sets token limit override
The admin UI now presents 3 modes via prompt dialog, and the API endpoint
handles each mode appropriately by updating the token usage bucket.
- Add publicModels and providerChain data structures for unified fallback
- Add two separate model adding sections in admin panel (public-facing and provider models)
- Add up/down buttons to reorder provider chain order
- Update server to use unified chain for all model fallbacks
- Auto-migrate legacy data on first load
- Update admin.js to handle new model structure and forms
When session.opencodeSessionId is null (indicating the session was reset
due to corruption or undo failure), ignore any opencodeSessionId sent
in the request body. This prevents the client from reusing a corrupted
session that was previously reset on the server.
When opencode undo command fails:
1. Reset the opencode session (both IDs set to null)
2. Still remove the message from history
3. Return success instead of error
This prevents corrupted sessions from blocking subsequent operations.
When a message fails with zero output and error status, undoing it now
resets the opencode session to ensure the next message starts fresh.
This prevents corrupted session reuse that was causing subsequent failures.
Prevents error when undoing messages that produced no output.
Checks for reply, partialOutput, or done status before sending
/undo command to opencode.
- Add CORS headers to backend server to allow mobile app requests
- Implement request timeout (10s) in capacitor-bridge.js to prevent hanging
- Add comprehensive logging throughout authentication flow
- Add detailed error reporting in initApp for better debugging
- Log all API requests with request IDs for traceability
This fixes the 'Loading Plugin Compass...' infinite loop issue caused by
missing CORS headers and unhandled network timeouts.
- Dockerfile: Build OpenCode CLI from source during Docker build instead of downloading from GitHub releases
- Disabled GitHub Actions workflow that was failing to create releases
- Removed getOpencodeSessionTokenUsage function that tried non-existent CLI commands (session info/usage/show)
- Token tracking now relies on 3 layers: result extraction, streaming capture, and estimation
- Strip double stars (**) and double hashtags (##) from plan message displayContent in both client and server
- Fix server restart error replacing plan message by skipping error state for plan messages
- Fix rate limiting regex pattern to use proper global flag
- Add tokenOverride field to token usage bucket
- Create POST /api/admin/accounts/tokens endpoint for setting manual token limits
- Update admin accounts page to display token usage and override status
- Add 'Set Tokens' button to manually override user token limits for the month
- Override takes precedence over plan-based limits when set
- Added missing closing brace for handleTopupConfirm function
- Removed extra closing brace after handleAdminMe function
- Admin functions (handleAdminTopupOptions, handleAdminTopupCheckout, handleAdminTopupConfirm) were incorrectly nested inside handleTopupConfirm scope, making them inaccessible to the router
Fixed ReferenceError: apiRateLimit is not defined that was causing
internal server errors on all pages. Added 4 missing Map variable
declarations that are used throughout the codebase for rate limiting
and CSRF protection.
Comprehensive fixes to prevent customer ID mismatches:
1. **Checkout creation now passes customer_id** (lines 13669, 13064, 13503):
- All checkouts (subscription, topup, PAYG) now call ensureDodoCustomer() first
- Pass existing customer_id to checkout body to prevent Dodo from creating duplicates
- Added customerId to metadata for tracking
2. **Subscription confirmation validates customer consistency** (line 13843):
- Logs warning when checkout returns different customer_id than stored
- Tracks which customer_id was used in checkout metadata
- Prevents silent customer ID overwrites
3. **ensureDodoCustomer handles multiple customers per email** (line 6774):
- Logs warning when multiple customers found for same email
- Checks ALL customers for active subscriptions
- Selects customer with active subscriptions if multiple exist
- Returns first customer only if no active subscriptions found
4. **Added missing return statements** (lines 12417, 12448):
- Prevents double response errors after successful plan changes
This ensures that:
- New subscriptions use existing customers instead of creating duplicates
- Plan changes work correctly even with multiple subscriptions
- Customer ID mismatches are detected and logged
- The correct customer (one with active subscriptions) is always used
- Added return statement after successful paid-to-free cancellation (line 12417)
- Added return statement after successful paid-to-paid plan change (line 12448)
- Prevents 'Cannot write headers after they are sent' error
- Each plan change now returns immediately with the updated account data
- Removed hardcoded subscription ID from code
- Rely on API queries to find subscriptions by customer or through fallback search
- Added proper logging to diagnose customer/subscription mismatches
- Add direct API call to fetch subscription sub_0NYKZRvba3g5KJfp8R5jp
- Log customer ID comparison to detect mismatches
- Update user record if subscription belongs to different customer
- This will help identify if duplicate customers exist in Dodo
- Query ALL subscriptions for customer without status filter first
- This handles customers with multiple subscriptions across different statuses
- Returns first active subscription found, or most recent if none active
- Added detailed logging to show all subscription IDs and statuses found
- Fallback to check individual statuses including cancelled/expired
Add comprehensive DEBUG logs to trace through:
- Customer lookup by email (request and response details)
- Subscription lookup by customer ID (for each status)
- Entry point when plan change is initiated
This will help identify exactly where the lookup is failing.
- Modified ensureDodoCustomer() to query existing customers by email before creating new ones
- This prevents duplicate customer records when dodoCustomerId is missing from database
- Added logging for both found existing customers and new customer creation
- Updated subscription lookup to check multiple statuses (active, pending, on_hold)
- Should resolve paid-to-paid and paid-to-free plan change issues for users missing subscription IDs
- Fix getBaseUrl() ReferenceError by changing to resolveBaseUrl(req) for free-to-paid upgrades
- Add subscription lookup by customer email when dodoSubscriptionId is missing
- Log critical issues when paid users have no subscription ID in database or Dodo
- Return clear error message to contact support when subscription cannot be found
- Prevent silent failures in plan changes from settings page
- Moved sticky positioning from mobile-only to global CSS for .top-left-actions
- Buttons now stay fixed at top above content on all screen sizes
- Includes various other app updates (version management, server improvements)
- Add 'cohere' to DEFAULT_PROVIDERS and PLANNING_PROVIDERS arrays in admin.js
- Add Cohere option to provider limits dropdown in admin.html
- Add 'cohere' to DEFAULT_PROVIDER_SEEDS, PLANNING_PROVIDERS, and KNOWN_USAGE_PROVIDERS in server.js
Cohere was already integrated in the opencode backend (SDK installed, provider registered, icons defined). These changes make it available in the admin panel for build message configuration.
- Parse model names like 'chutes/deepseek-ai/DeepSeek-V3.2-TEE'
- Extract provider prefix before '/' to detect chutes, cerebras, etc.
- This fixes provider detection when admin panel sets wrong provider
- Support providers as array of strings: [opencode, chutes]
- Support providers as array of objects: [{provider: opencode}]
- This fixes provider detection for Chutes and other providers
- Move loadAdminModelStore() before loadState() in bootstrap()
- This ensures adminModels is available when ensureOpencodeConfig is called
- Fixes issue where Chutes provider was not being configured