Transform this plugin into a universal OpenAI-compatible model discovery system that:
- Scans ALL providers with OpenAI-compatible endpoints (regardless of npm package)
- Automatically discovers available models via
/v1/modelsendpoint - Injects unconfigured models into provider configurations
- Works seamlessly with LM Studio, Ollama, LocalAI, and any OpenAI-compatible API
- Supports providers using
@ai-sdk/anthropicwith OpenAI-compatible backends (e.g., Ollama Anthropic mode)
Note: This plugin focuses exclusively on automatic model discovery. It does NOT perform validation (e.g., checking if a model is loaded/available before making requests). Validation is the responsibility of the AI SDK or the underlying provider.
- Goal: Identify all OpenAI-compatible providers in config
- Detection Logic:
- Strict:
npm === "@ai-sdk/openai-compatible" - URL-based:
baseURLcontains/v1/pattern (supports@ai-sdk/anthropicwith OpenAI-compatible backends) - Combined:
canDiscoverModels()returns true if either condition matches
- Strict:
- Changes:
- Add
hasOpenAICompatibleURL()function - Add
canDiscoverModels()function combining both checks - Support multiple providers simultaneously
- Handle mixed provider configurations (OpenAI, Anthropic, + OpenAI-compatible)
- Add
- Acceptance Criteria:
- TypeScript compilation passes
- Correctly identifies all OpenAI-compatible providers
- Skips non-compatible providers gracefully
- Supports
@ai-sdk/anthropicwith OpenAI-compatible URLs
- Goal: Verify provider accessibility before model discovery
- Changes:
- Add health check for each provider's
/v1/modelsendpoint - Implement connection timeout handling
- Provide clear offline/online status reporting
- Add health check for each provider's
- Acceptance Criteria:
- Handles offline providers without blocking
- Reports provider status clearly in logs
- Goal: Query models from all accessible providers
- Changes:
- Iterate through all OpenAI-compatible providers
- Fetch models via
/v1/modelsendpoint for each - Handle partial failures (some providers offline)
- Aggregate discovery results
- Acceptance Criteria:
- Discovers models from multiple providers
- Continues if one provider fails
- Reports discovery summary
- Goal: Add discovered models to provider configs without overwriting explicit config
- Changes:
- Preserve explicitly configured models
- Merge only new/unconfigured models
- Apply smart model formatting (name, modalities, owner)
- Handle model key normalization
- Acceptance Criteria:
- Doesn't overwrite user-defined model configs
- Correctly formats model metadata
- Handles special characters in model IDs
- Goal: Classify discovered models by type
- Changes:
- Detect chat vs embedding models by ID patterns
- Set appropriate modalities
- Extract organization owner from model ID
- Acceptance Criteria:
- Correctly categorizes chat/embedding models
- Sets modalities appropriately
- Goal: Provide actionable error messages for common issues
- Changes:
- Categorize errors: offline, timeout, not_found, permission, network
- Generate step-by-step fix suggestions
- Provide provider-specific guidance
- Acceptance Criteria:
- Errors are categorized correctly
- Users receive actionable fix suggestions
- Goal: Handle transient failures gracefully
- Changes:
- Implement exponential backoff retry
- Add max retry limits
- Provide fallback behavior
- Acceptance Criteria:
- Retries transient failures
- Doesn't block startup on failures
- Goal: Provide non-intrusive status updates
- Changes:
- Success/failure toasts for model discovery
- Progress indicators during discovery
- Error notifications with suggestions
- Acceptance Criteria:
- Shows appropriate toasts
- Handles missing toast API gracefully
- Goal: Reduce API calls with intelligent caching
- Changes:
- Implement TTL-based cache (15s default)
- Cache invalidation on errors
- Cache warming on startup
- Prevent memory leaks (max 50 entries)
- Acceptance Criteria:
- Reduces API calls significantly
- Cache expires appropriately
- Handles stale data gracefully
- Goal: Provide visibility into cache behavior
- Changes:
- Expose cache stats (size, entries, age)
- Add cache invalidation methods
- Log cache operations
- Acceptance Criteria:
- Can inspect cache state
- Provides hit/miss visibility
- Goal: Monitor session events for provider status
- Changes:
- Track session.created/updated events
- Log provider health during session
- Provide proactive alerts
- Acceptance Criteria:
- Monitors session health
- Doesn't block event processing
- Goal: Define configuration schema for plugin
- Changes:
- Define
PluginConfiginterface with providers and discovery sections - Support tuple format:
["plugin-name", { config }] - Document configuration options
- Define
- Acceptance Criteria:
- Config schema is well-defined
- Supports OpenCode's tuple format
- Goal: Allow filtering which providers to discover models for
- Changes:
- Implement
providers.include(whitelist) - Implement
providers.exclude(blacklist) - Priority logic:
includenon-empty → ignoreexclude - Update
enhanceConfig()to respect filters
- Implement
- Acceptance Criteria:
- Only discovers models for included providers (when include non-empty)
- Excludes work only when include is empty
- Logs which providers were filtered
- Goal: Allow configuring discovery behavior
- Changes:
discovery.enabled- toggle discovery on/offdiscovery.ttl- configure cache TTL (default 15000ms)
- Acceptance Criteria:
- Discovery can be disabled entirely
- Cache TTL is configurable
- Goal: Receive plugin config from OpenCode
- Status: CONFIRMED WORKING
- Finding: OpenCode passes plugin configuration via the
optionsparameter (second argument to Plugin function) - Plugin Signature:
Plugin = (input: PluginInput, options?: PluginOptions) => Promise<Hooks> - Changes:
- Updated plugin to use
optionsparameter directly - Simplified config parsing since OpenCode passes config correctly
- Updated plugin to use
- Acceptance Criteria:
- Plugin correctly receives configuration from OpenCode options
- Tuple format
["plugin-name", { config }]works correctly
// Provider is OpenAI-compatible if:
provider.npm === "@ai-sdk/openai-compatible"- LM Studio (default port: 1234)
- Ollama (port: 11434)
- LocalAI (port: 8080)
- Any provider using
@ai-sdk/openai-compatible - Any provider with OpenAI-compatible URL (baseURL contains
/v1/)- Including
@ai-sdk/anthropicwith OpenAI-compatible backends (e.g., Ollama Anthropic mode)
- Including
- Iterate all providers in config
- Filter using
canDiscoverModels()(strict npm OR URL-based) - Check health via
/v1/models - Fetch available models
- Merge into config (preserve existing)
- Warm cache
- Unit tests for provider detection
- Integration tests for discovery flow
- Mock tests for error scenarios
- Multi-provider scenarios
The following items are not planned for this plugin:
- Validation: This plugin focuses on automatic model discovery only. Validation (checking if a model is loaded/available) is handled by the AI SDK or provider.
- Provider-specific management tools (load/unload/switch models, server-side controls)
- Server start/stop controls
- Model search tools
- Performance analytics
- System message transformation hooks
- Session compaction hooks
- Text completion hooks
- Multi-instance support
- Team collaboration features
- Telemetry collection
These could be revisited in future iterations if there's demand.