Skip to content

Commit 45707b6

Browse files
feat: Add region property to ModelConfig (#201)
**Requirements** - [x] I have added test coverage for new or changed functionality - [x] I have followed the repository's [pull request submission guidelines](../blob/main/CONTRIBUTING.md#submitting-pull-requests) - [x] I have validated my changes against all supported platform versions **Related issues** https://launchdarkly.atlassian.net/jira/software/c/projects/AIC/boards/2045?selectedIssue=AIC-2689 **Describe the solution you've provided** Adds the `region` property to the `ModelConfig` object **Additional context** Some model providers, namely Bedrock, require including a `region` field on a given call. A call for a sonnet model might look like: `global.anthropic.sonnet-4-7` or `us.anthropic.sonnet-4-7` etc. This field was added on the UI for Bedrock models and is optionally includable. Users would be expected to prepend their region to their model names if they're using a provider that requires it. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Backward-compatible optional field on model config parsing with no changes to auth or provider call paths in this diff. > > **Overview** > Adds optional **`region`** on **`ModelConfig`** so AI Config flag variations can carry deployment region (e.g. Bedrock `us` vs `global`) without encoding it only in the model name. > > **`LDAIClient`** now reads `model.region` from evaluated variations when building completion/agent/judge configs, and **`to_dict()`** includes **`region`** for round-tripping. Omitted **`region`** stays **`None`**, so existing flags behave unchanged. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 219f71b. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
2 parents 5d8da38 + 219f71b commit 45707b6

3 files changed

Lines changed: 67 additions & 2 deletions

File tree

packages/sdk/server-ai/src/ldai/client.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,10 +832,12 @@ def __evaluate(
832832
if 'model' in variation and isinstance(variation['model'], dict):
833833
parameters = variation['model'].get('parameters', None)
834834
custom = variation['model'].get('custom', None)
835+
region = variation['model'].get('region', None)
835836
model = ModelConfig(
836837
name=variation['model']['name'],
837838
parameters=parameters,
838-
custom=custom
839+
custom=custom,
840+
region=region,
839841
)
840842

841843
variation_key = variation.get('_ldMeta', {}).get('variationKey', '')

packages/sdk/server-ai/src/ldai/models.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,23 @@ class ModelConfig:
5252
Configuration related to the model.
5353
"""
5454

55-
def __init__(self, name: str, parameters: Optional[Dict[str, Any]] = None, custom: Optional[Dict[str, Any]] = None):
55+
def __init__(
56+
self,
57+
name: str,
58+
parameters: Optional[Dict[str, Any]] = None,
59+
custom: Optional[Dict[str, Any]] = None,
60+
region: Optional[str] = None,
61+
):
5662
"""
5763
:param name: The name of the model.
5864
:param parameters: Additional model-specific parameters.
5965
:param custom: Additional customer provided data.
66+
:param region: The region the model is deployed in.
6067
"""
6168
self._name = name
6269
self._parameters = parameters
6370
self._custom = custom
71+
self._region = region
6472

6573
@property
6674
def name(self) -> str:
@@ -93,6 +101,13 @@ def get_custom(self, key: str) -> Any:
93101

94102
return self._custom.get(key)
95103

104+
@property
105+
def region(self) -> Optional[str]:
106+
"""
107+
The region the model is deployed in.
108+
"""
109+
return self._region
110+
96111
def to_dict(self) -> dict:
97112
"""
98113
Render the given model config as a dictionary object.
@@ -101,6 +116,7 @@ def to_dict(self) -> dict:
101116
'name': self._name,
102117
'parameters': self._parameters,
103118
'custom': self._custom,
119+
'region': self._region,
104120
}
105121

106122

packages/sdk/server-ai/tests/test_model_config.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,23 @@ def td() -> TestData:
3131
.variation_for_all(0)
3232
)
3333

34+
td.update(
35+
td.flag('model-config-with-region')
36+
.variations(
37+
{
38+
'model': {
39+
'name': 'anthropic.claude-opus-4-7',
40+
'parameters': {},
41+
'region': 'us',
42+
},
43+
'provider': {'name': 'Bedrock'},
44+
'messages': [{'role': 'system', 'content': 'Hello!'}],
45+
'_ldMeta': {'enabled': True, 'variationKey': 'us-variation', 'version': 1},
46+
},
47+
)
48+
.variation_for_all(0)
49+
)
50+
3451
td.update(
3552
td.flag('multiple-messages')
3653
.variations(
@@ -482,6 +499,36 @@ def test_create_tracker_preserves_config_metadata():
482499
assert 'runId' in track_data
483500

484501

502+
def test_model_config_region():
503+
model = ModelConfig('fakeModel', region='us')
504+
assert model.region == 'us'
505+
506+
507+
def test_model_config_region_defaults_to_none():
508+
model = ModelConfig('fakeModel')
509+
assert model.region is None
510+
511+
512+
def test_model_config_region_from_flag(ldai_client: LDAIClient):
513+
context = Context.create('user-key')
514+
default = AICompletionConfigDefault(enabled=True, model=ModelConfig('fake-model'), messages=[])
515+
516+
config = ldai_client.completion_config('model-config-with-region', context, default)
517+
518+
assert config.model is not None
519+
assert config.model.region == 'us'
520+
521+
522+
def test_model_config_no_region_is_none(ldai_client: LDAIClient):
523+
context = Context.create('user-key')
524+
default = AICompletionConfigDefault(enabled=True, model=ModelConfig('fake-model'), messages=[])
525+
526+
config = ldai_client.completion_config('model-config', context, default)
527+
528+
assert config.model is not None
529+
assert config.model.region is None
530+
531+
485532
def test_create_tracker_each_call_has_different_run_id():
486533
from unittest.mock import Mock
487534

0 commit comments

Comments
 (0)