Skip to content

feat: bring model-enrichment-capabilities up to speed with main#21

Merged
Alph4d0g merged 31 commits into
mainfrom
feat/model-enrichment-capabilities
May 17, 2026
Merged

feat: bring model-enrichment-capabilities up to speed with main#21
Alph4d0g merged 31 commits into
mainfrom
feat/model-enrichment-capabilities

Conversation

@Alph4d0g
Copy link
Copy Markdown
Owner

This PR brings the feat/model-enrichment-capabilities branch up to speed with main after the v1.2.0 release.

Changes include:

  • Version bump to 1.2.0
  • CHANGELOG and README updates
  • All model enrichment capabilities from the original PR
  • Merge commit to reconcile with main

abien and others added 30 commits May 16, 2026 08:37
… resolution

- Add env var fallback for API key in config hook (OMNIROUTE_API_KEY)
- Generate modelMetadata from enriched models so OpenCode applies capabilities
- Add top-level capability fields (temperature, reasoning, attachment, tool_call, modalities) to provider model output
- Generate reasoning effort variants (low/medium/high) for reasoning models
- Add provider aliases: glmt/glm→zai-coding-plan, kimi-coding/kmc→moonshotai, gh/github→google
- Add subscription fallback: zai-coding-plan→zai, kimi-for-coding→moonshotai
- Add model aliases for naming mismatches (kimi-k2.6-thinking→kimi-k2-thinking)
- Strip reasoning effort variant suffixes (gpt-5.5-xhigh→gpt-5.5) for lookup
- Close 19 of 132 models with 4096 default context limits
Preserve user modelMetadata while merging generated capabilities, propagate new capability fields through models.dev and combo paths, and consolidate alias resolution.
Treat missing attachment capability as unknown instead of false when folding combo model capabilities, while still honoring explicit false values.
Avoid falling back to vision support when models.dev or combo metadata explicitly marks attachments unsupported.
- Fix temperature AND-chain bug in calculateLowestCommonCapabilities by tracking hasTemperatureMetadata
- Fix reasoning AND-chain bug in calculateLowestCommonCapabilities by tracking hasReasoningMetadata
- Respect explicit supportsAttachment=false for vision models in toProviderModel
- Add normalized key candidates to getModelLookupCandidates for better alias/variant matching

Addresses feedback from Copilot, Gemini Code Assist, and Kilo Code Bot reviews.
- Expand sanitizeForLog to strip all control chars except tab (was only \r\n)
- Export sanitizeForLog from omniroute-combos.ts for reuse in plugin.ts
- Sanitize model IDs and external values in plugin.ts debug/warn lines:
  - Available models list (line 146)
  - provider.api / apiMode mismatch (lines 209, 215)
  - Unsupported apiMode option (line 231)
  - Unsupported baseURL protocol (line 254)
  - Invalid baseURL (line 260)
  - Invalid metadata field (line 371)
  - Intercepting request URL (line 581)
- Include models.ts null-data fix in same commit

Refs: task-10-log-injection
…ariant+alias, and subscription fallback tests

- Task 15: Add test verifying single model and combo-with-self produce identical capabilities
- Task 17: Add temperature/reasoning combo tests (mixed defined/undefined, false override, all three capabilities, undefined single model)
- Task 18: Add variant suffix stripping + alias resolution integration test
- Task 19: Add subscription provider fallback enrichment test
- Add getDummyBaseUrl(port) helper function to eliminate magic numbers
- Replace all hardcoded http://localhost:20xxx URLs with helper calls
- Keeps assertions and external URLs using hardcoded strings for clarity
- Fix array-based metadata merge precedence: userConfig now comes first
  in first-match-wins systems instead of being overridden by generated blocks
- Add validation for array-based user metadata blocks to filter out invalid
  entries before merging
- Merge metadata for unknown provider prefixes instead of overwriting,
  preserving all available metadata
- Simplify deduplication logic: remove unreachable isAlias check and merge
  alias metadata into canonical entries, preferring existing (canonical) fields
- Update test expectations to match new array ordering (user first, generated second)
- Bump version from 1.1.4 to 1.2.0 in package.json
- Add comprehensive CHANGELOG entry for v1.2.0 covering:
  - Model metadata normalization (camelCase, snake_case, capabilities)
  - Provider alias deduplication system
  - Array-based metadata validation and precedence fixes
  - Metadata key canonicalization
  - All gemini-code-assist review feedback addressed
- Update README with:
  - New features: metadata normalization, alias deduplication, variant support
  - Updated OmniRouteModel type documentation with native fields
  - Star History graph at the bottom
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces comprehensive model metadata normalization and provider alias deduplication. It updates the OmniRouteModel interface to support snake_case fields and a capabilities object, ensuring proper precedence during normalization. A new deduplication system groups models by canonical IDs. Additionally, logging has been moved to an asynchronous implementation with input sanitization, and user-provided metadata merging now respects canonical keys and precedence. Feedback highlights a potential logic error where vision support is incorrectly inferred from general attachments and notes that string matches in metadata blocks require canonicalization to function with the new deduplication logic.

Comment thread src/models.ts
Comment on lines +75 to +79
supportsVision:
model.supportsVision ??
model.vision ??
capabilities.vision ??
capabilities.attachment,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The fallback to capabilities.attachment for supportsVision might be incorrect. While models with vision capabilities typically support attachments (images), the reverse is not always true—a model might support non-image attachments (like documents) without supporting vision. This could lead to the plugin incorrectly advertising image support for non-vision models, causing issues when users attempt to send images to them.

Comment thread src/plugin.ts
Comment on lines +365 to +372
const validUserConfig = userConfig.filter((block) => {
const validation = isValidModelMetadata(block);
if (!validation.valid) {
warn(`Invalid metadata block for match "${sanitizeForLog(String(block.match))}" (field: ${sanitizeForLog(validation.field ?? '')}), skipping`);
return false;
}
return true;
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

When modelMetadata is provided as an array of blocks, string matches in the match field are not canonicalized. Since the plugin now deduplicates and canonicalizes model IDs to their canonical forms (e.g., codex/ instead of cx/), user-provided metadata blocks using alias IDs in the match string will fail to match. Consider resolving provider aliases for string matches in the match field to maintain compatibility.

    const validUserConfig = userConfig.filter((block) => {
      const validation = isValidModelMetadata(block);
      if (!validation.valid) {
        warn(`Invalid metadata block for match "${sanitizeForLog(String(block.match))}" (field: ${sanitizeForLog(validation.field ?? '')}), skipping`);
        return false;
      }
      // Canonicalize string matches to ensure they work with deduplicated model IDs
      if (typeof block.match === 'string') {
        block.match = resolveProviderAliasForMetadata(block.match);
      }
      return true;
    });

@Alph4d0g Alph4d0g merged commit 4362383 into main May 17, 2026
3 checks passed
@Alph4d0g Alph4d0g deleted the feat/model-enrichment-capabilities branch May 19, 2026 09:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants