ListModels returns available models with their metadata. Results are cached after the first successful call to avoid rate limiting. The cache is cleared when the client disconnects.
(ctx context.Context)
| 1612 | // Results are cached after the first successful call to avoid rate limiting. |
| 1613 | // The cache is cleared when the client disconnects. |
| 1614 | func (c *Client) ListModels(ctx context.Context) ([]ModelInfo, error) { |
| 1615 | // Use mutex for locking to prevent race condition with concurrent calls |
| 1616 | c.modelsCacheMux.Lock() |
| 1617 | defer c.modelsCacheMux.Unlock() |
| 1618 | |
| 1619 | // Check cache (already inside lock) |
| 1620 | if c.modelsCache != nil { |
| 1621 | result := make([]ModelInfo, len(c.modelsCache)) |
| 1622 | copy(result, c.modelsCache) |
| 1623 | return result, nil |
| 1624 | } |
| 1625 | |
| 1626 | var models []ModelInfo |
| 1627 | if c.onListModels != nil { |
| 1628 | // Use custom handler instead of CLI RPC |
| 1629 | var err error |
| 1630 | models, err = c.onListModels(ctx) |
| 1631 | if err != nil { |
| 1632 | return nil, err |
| 1633 | } |
| 1634 | } else { |
| 1635 | if c.client == nil { |
| 1636 | return nil, fmt.Errorf("client not connected") |
| 1637 | } |
| 1638 | // Cache miss - fetch from backend while holding lock |
| 1639 | result, err := c.client.Request(ctx, "models.list", listModelsRequest{}) |
| 1640 | if err != nil { |
| 1641 | return nil, err |
| 1642 | } |
| 1643 | |
| 1644 | var response listModelsResponse |
| 1645 | if err := json.Unmarshal(result, &response); err != nil { |
| 1646 | return nil, fmt.Errorf("failed to unmarshal models response: %w", err) |
| 1647 | } |
| 1648 | models = response.Models |
| 1649 | } |
| 1650 | |
| 1651 | // Update cache before releasing lock (copy to prevent external mutation) |
| 1652 | cache := make([]ModelInfo, len(models)) |
| 1653 | copy(cache, models) |
| 1654 | c.modelsCache = cache |
| 1655 | |
| 1656 | // Return a copy to prevent cache mutation |
| 1657 | result := make([]ModelInfo, len(models)) |
| 1658 | copy(result, models) |
| 1659 | return result, nil |
| 1660 | } |
| 1661 | |
| 1662 | // minProtocolVersion is the minimum protocol version this SDK can communicate with. |
| 1663 | const minProtocolVersion = 3 |