diff --git a/src/otari/_client/models/execution_state.py b/src/otari/_client/models/execution_state.py index 49a88a93..b1eb581e 100644 --- a/src/otari/_client/models/execution_state.py +++ b/src/otari/_client/models/execution_state.py @@ -20,7 +20,7 @@ class ExecutionState(str, Enum): """ - Whether the remote tool may have run (R-ERR-2). A retry-safety classification, not a description of how the HTTP request went. ``NOT_STARTED`` is Otari saying it knows the tool did not run; ``OUTCOME_UNKNOWN`` is Otari saying it cannot know, which is the only honest answer once the transport has begun writing ``tools/call``. + Whether the remote tool may have run. A retry-safety classification, not a description of how the HTTP request went. ``NOT_STARTED`` is Otari saying it knows the tool did not run; ``OUTCOME_UNKNOWN`` is Otari saying it cannot know, which is the only honest answer once the transport has begun writing ``tools/call``. """ """ diff --git a/src/otari/_client/models/mcp_error_body.py b/src/otari/_client/models/mcp_error_body.py index 0c6a63ab..55df9dc5 100644 --- a/src/otari/_client/models/mcp_error_body.py +++ b/src/otari/_client/models/mcp_error_body.py @@ -26,7 +26,7 @@ class McpErrorBody(BaseModel): """ - The one error shape both stored-server endpoints return (R-ERR-1). + The one error shape both stored-server endpoints return. """ # noqa: E501 code: StrictStr detail: StrictStr diff --git a/src/otari/_client/models/mcp_execute_request.py b/src/otari/_client/models/mcp_execute_request.py index 3d33e846..428ebd19 100644 --- a/src/otari/_client/models/mcp_execute_request.py +++ b/src/otari/_client/models/mcp_execute_request.py @@ -27,7 +27,7 @@ class McpExecuteRequest(BaseModel): """ - One stored server, and the exact call the application authorized. No inline server fields (R-REQ-4): a caller registers a remote MCP server through the control plane once and refers to it by id afterwards, which keeps URLs, credentials, revocation and allowlist policy on Otari's side of the boundary instead of in every request. Extras are forbidden rather than ignored, so a caller still sending the old inline ``server`` block is told its configuration was not used instead of watching Otari quietly execute against a different server than the one it named. + One stored server, and the exact call the application authorized. No inline server fields: a caller registers a remote MCP server through the control plane once and refers to it by id afterwards, which keeps URLs, credentials, revocation and allowlist policy on Otari's side of the boundary instead of in every request. Extras are forbidden rather than ignored, so a caller still sending the old inline ``server`` block is told its configuration was not used instead of watching Otari quietly execute against a different server than the one it named. """ # noqa: E501 arguments: Optional[Dict[str, Any]] = Field(default=None, description="The exact caller-authorized JSON-object arguments.") client_execution_id: UUID = Field(description="A caller-generated UUID, for correlation only. It is not proof of approval and not an idempotency key: repeating a request with the same value may execute the tool again, so this request must never be retried automatically.") diff --git a/src/otari/_client/models/mcp_tool_definition.py b/src/otari/_client/models/mcp_tool_definition.py index 30ce3d54..de993a5f 100644 --- a/src/otari/_client/models/mcp_tool_definition.py +++ b/src/otari/_client/models/mcp_tool_definition.py @@ -25,7 +25,7 @@ class McpToolDefinition(BaseModel): """ - One live tool a caller-orchestrated application may expose to its model. ``annotations`` is the remote server's own metadata, passed through as untrusted data. Otari never turns ``readOnlyHint`` into an authorization decision (R-RISK-1); each application owns its risk policy, and a server cannot waive an application's approval gate by labeling itself read-only. + One live tool a caller-orchestrated application may expose to its model. ``annotations`` is the remote server's own metadata, passed through as untrusted data. Otari never turns ``readOnlyHint`` into an authorization decision; each application owns its risk policy, and a server cannot waive an application's approval gate by labeling itself read-only. """ # noqa: E501 annotations: Optional[Dict[str, Any]] = Field(default=None, description="Provider-native request fields used as defaults (e.g. exa's 'type', searxng's 'engines').") description: Optional[StrictStr] = Field(default=None, description="The server's own description, untrusted.") diff --git a/src/otari/_client/models/mcp_tool_warning.py b/src/otari/_client/models/mcp_tool_warning.py index 65414841..4c6aa33f 100644 --- a/src/otari/_client/models/mcp_tool_warning.py +++ b/src/otari/_client/models/mcp_tool_warning.py @@ -25,7 +25,7 @@ class McpToolWarning(BaseModel): """ - One tool that was omitted, and the code that omitted it (R-SCHEMA-3). + One tool that was omitted, and the code that omitted it. """ # noqa: E501 code: StrictStr tool_name: StrictStr diff --git a/src/otari/_client/models/mcp_tools_response.py b/src/otari/_client/models/mcp_tools_response.py index 675c6475..ed5a7d9d 100644 --- a/src/otari/_client/models/mcp_tools_response.py +++ b/src/otari/_client/models/mcp_tools_response.py @@ -29,7 +29,7 @@ class McpToolsResponse(BaseModel): """ - The authorized catalog for one stored server. Carries no server URL, no credential, and no allowlist entry that the live catalog did not return (R-DISC-2). ``server_revision`` is what an application persists with a proposed call and sends back to ``/api/v1/mcp/execute``, so a stored-configuration change between the two is refused rather than executed. + The authorized catalog for one stored server. Carries no server URL, no credential, and no allowlist entry that the live catalog did not return. ``server_revision`` is what an application persists with a proposed call and sends back to ``/api/v1/mcp/execute``, so a stored-configuration change between the two is refused rather than executed. """ # noqa: E501 server_id: UUID server_revision: StrictStr = Field(description="An opaque revision of the stored server's URL, credential, enabled state and allowlist. It detects Otari-side and platform-side configuration changes only: a remote server that changes its own catalog or a tool's behavior behind an unchanged URL will not move it.") diff --git a/src/otari/_client/models/rate_limit_rule_create.py b/src/otari/_client/models/rate_limit_rule_create.py index 693a87eb..c3633d56 100644 --- a/src/otari/_client/models/rate_limit_rule_create.py +++ b/src/otari/_client/models/rate_limit_rule_create.py @@ -30,11 +30,12 @@ class RateLimitRuleCreate(BaseModel): """ # noqa: E501 lease_sec: Optional[Union[Annotated[float, Field(strict=True, gt=0.0)], Annotated[int, Field(strict=True, gt=0)]]] = Field(default=900.0, description="How long a max_concurrent slot is held at most. A slot is given back when its response ends; this bounds what a process that dies mid-request keeps.") max_concurrent: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field(default=None, description="Requests in flight at once.") + models: Optional[List[StrictStr]] = Field(default=None, description="The models a `per: model` rule limits, each as instance:model (the provider instance the model is called through, then the model), each counted on its own. Required there and refused on any other rule.") name: Annotated[str, Field(strict=True)] = Field(description="Names the rule in a 429's detail and in the counter's key. Unique across rate_limits.") per: StrictStr = Field(description="What one count is shared by.") rpm: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field(default=None, description="Requests per minute.") tpm: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field(default=None, description="Tokens per minute. A request is admitted on its estimate (prompt plus max output, or budget_estimate_default_output_tokens) and charged what it used once it completes.") - __properties: ClassVar[List[str]] = ["lease_sec", "max_concurrent", "name", "per", "rpm", "tpm"] + __properties: ClassVar[List[str]] = ["lease_sec", "max_concurrent", "models", "name", "per", "rpm", "tpm"] @field_validator('name') def name_validate_regular_expression(cls, value): @@ -49,8 +50,8 @@ def name_validate_regular_expression(cls, value): @field_validator('per') def per_validate_enum(cls, value): """Validates the enum""" - if value not in set(['deployment', 'key', 'user']): - raise ValueError("must be one of enum values ('deployment', 'key', 'user')") + if value not in set(['deployment', 'key', 'user', 'model']): + raise ValueError("must be one of enum values ('deployment', 'key', 'user', 'model')") return value model_config = ConfigDict( @@ -97,6 +98,11 @@ def to_dict(self) -> Dict[str, Any]: if self.max_concurrent is None and "max_concurrent" in self.model_fields_set: _dict['max_concurrent'] = None + # set to None if models (nullable) is None + # and model_fields_set contains the field + if self.models is None and "models" in self.model_fields_set: + _dict['models'] = None + # set to None if rpm (nullable) is None # and model_fields_set contains the field if self.rpm is None and "rpm" in self.model_fields_set: @@ -121,6 +127,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: _obj = cls.model_validate({ "lease_sec": obj.get("lease_sec") if obj.get("lease_sec") is not None else 900.0, "max_concurrent": obj.get("max_concurrent"), + "models": obj.get("models"), "name": obj.get("name"), "per": obj.get("per"), "rpm": obj.get("rpm"), diff --git a/src/otari/_client/models/rate_limit_rule_public.py b/src/otari/_client/models/rate_limit_rule_public.py index ebbd8682..0f48a892 100644 --- a/src/otari/_client/models/rate_limit_rule_public.py +++ b/src/otari/_client/models/rate_limit_rule_public.py @@ -31,6 +31,7 @@ class RateLimitRulePublic(BaseModel): """ # noqa: E501 lease_sec: Optional[Union[Annotated[float, Field(strict=True, gt=0.0)], Annotated[int, Field(strict=True, gt=0)]]] = Field(default=900.0, description="How long a max_concurrent slot is held at most. A slot is given back when its response ends; this bounds what a process that dies mid-request keeps.") max_concurrent: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field(default=None, description="Requests in flight at once.") + models: Optional[List[StrictStr]] = Field(default=None, description="The models a `per: model` rule limits, each as instance:model (the provider instance the model is called through, then the model), each counted on its own. Required there and refused on any other rule.") name: Annotated[str, Field(strict=True)] = Field(description="Names the rule in a 429's detail and in the counter's key. Unique across rate_limits.") per: StrictStr = Field(description="What one count is shared by.") rpm: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field(default=None, description="Requests per minute.") @@ -38,7 +39,7 @@ class RateLimitRulePublic(BaseModel): tpm: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field(default=None, description="Tokens per minute. A request is admitted on its estimate (prompt plus max output, or budget_estimate_default_output_tokens) and charged what it used once it completes.") updated_at: Optional[datetime] = Field(default=None, description="When a stored rule last changed.") additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["lease_sec", "max_concurrent", "name", "per", "rpm", "source", "tpm", "updated_at"] + __properties: ClassVar[List[str]] = ["lease_sec", "max_concurrent", "models", "name", "per", "rpm", "source", "tpm", "updated_at"] @field_validator('name') def name_validate_regular_expression(cls, value): @@ -53,8 +54,8 @@ def name_validate_regular_expression(cls, value): @field_validator('per') def per_validate_enum(cls, value): """Validates the enum""" - if value not in set(['deployment', 'key', 'user']): - raise ValueError("must be one of enum values ('deployment', 'key', 'user')") + if value not in set(['deployment', 'key', 'user', 'model']): + raise ValueError("must be one of enum values ('deployment', 'key', 'user', 'model')") return value @field_validator('source') @@ -115,6 +116,11 @@ def to_dict(self) -> Dict[str, Any]: if self.max_concurrent is None and "max_concurrent" in self.model_fields_set: _dict['max_concurrent'] = None + # set to None if models (nullable) is None + # and model_fields_set contains the field + if self.models is None and "models" in self.model_fields_set: + _dict['models'] = None + # set to None if rpm (nullable) is None # and model_fields_set contains the field if self.rpm is None and "rpm" in self.model_fields_set: @@ -144,6 +150,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: _obj = cls.model_validate({ "lease_sec": obj.get("lease_sec") if obj.get("lease_sec") is not None else 900.0, "max_concurrent": obj.get("max_concurrent"), + "models": obj.get("models"), "name": obj.get("name"), "per": obj.get("per"), "rpm": obj.get("rpm"), diff --git a/src/otari/_client/models/rate_limit_rule_update.py b/src/otari/_client/models/rate_limit_rule_update.py index 957b4bf2..e5ea7388 100644 --- a/src/otari/_client/models/rate_limit_rule_update.py +++ b/src/otari/_client/models/rate_limit_rule_update.py @@ -30,10 +30,11 @@ class RateLimitRuleUpdate(BaseModel): """ # noqa: E501 lease_sec: Optional[Union[Annotated[float, Field(strict=True, gt=0.0)], Annotated[int, Field(strict=True, gt=0)]]] = Field(default=None, description="How long a max_concurrent slot is held at most.") max_concurrent: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field(default=None, description="Requests in flight at once.") + models: Optional[List[StrictStr]] = Field(default=None, description="The instance:model names a per: model rule limits; null for any other rule.") per: Optional[StrictStr] = Field(default=None, description="What one count is shared by.") rpm: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field(default=None, description="Requests per minute.") tpm: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field(default=None, description="Tokens per minute.") - __properties: ClassVar[List[str]] = ["lease_sec", "max_concurrent", "per", "rpm", "tpm"] + __properties: ClassVar[List[str]] = ["lease_sec", "max_concurrent", "models", "per", "rpm", "tpm"] @field_validator('per') def per_validate_enum(cls, value): @@ -41,8 +42,8 @@ def per_validate_enum(cls, value): if value is None: return value - if value not in set(['deployment', 'key', 'user']): - raise ValueError("must be one of enum values ('deployment', 'key', 'user')") + if value not in set(['deployment', 'key', 'user', 'model']): + raise ValueError("must be one of enum values ('deployment', 'key', 'user', 'model')") return value model_config = ConfigDict( @@ -94,6 +95,11 @@ def to_dict(self) -> Dict[str, Any]: if self.max_concurrent is None and "max_concurrent" in self.model_fields_set: _dict['max_concurrent'] = None + # set to None if models (nullable) is None + # and model_fields_set contains the field + if self.models is None and "models" in self.model_fields_set: + _dict['models'] = None + # set to None if per (nullable) is None # and model_fields_set contains the field if self.per is None and "per" in self.model_fields_set: @@ -123,6 +129,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: _obj = cls.model_validate({ "lease_sec": obj.get("lease_sec"), "max_concurrent": obj.get("max_concurrent"), + "models": obj.get("models"), "per": obj.get("per"), "rpm": obj.get("rpm"), "tpm": obj.get("tpm")