meshagent-api 0.52.4__tar.gz → 0.53.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. {meshagent_api-0.52.4/meshagent_api.egg-info → meshagent_api-0.53.0}/PKG-INFO +1 -1
  2. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/client.py +34 -3
  3. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/client_test.py +54 -0
  4. meshagent_api-0.53.0/meshagent/api/version.py +1 -0
  5. {meshagent_api-0.52.4 → meshagent_api-0.53.0/meshagent_api.egg-info}/PKG-INFO +1 -1
  6. meshagent_api-0.52.4/meshagent/api/version.py +0 -1
  7. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/LICENSE +0 -0
  8. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/MANIFEST.in +0 -0
  9. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/README.md +0 -0
  10. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/__init__.py +0 -0
  11. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/agent_content.py +0 -0
  12. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/aiohttp_redaction.py +0 -0
  13. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/chan.py +0 -0
  14. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/crdt.py +0 -0
  15. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/dataset_schema.py +0 -0
  16. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/entrypoint.js +0 -0
  17. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/error_codes.py +0 -0
  18. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/helpers.py +0 -0
  19. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/http.py +0 -0
  20. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/image_runtime.py +0 -0
  21. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/keys.py +0 -0
  22. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/llm_router_config.py +0 -0
  23. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/managed_agents.py +0 -0
  24. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/managed_agents_test.py +0 -0
  25. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/messaging.py +0 -0
  26. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/messaging_test.py +0 -0
  27. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/mime_types.py +0 -0
  28. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/mime_types_test.py +0 -0
  29. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/oauth.py +0 -0
  30. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/oauth_branding.py +0 -0
  31. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/oauth_scopes.py +0 -0
  32. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/oauth_scopes_test.py +0 -0
  33. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/participant.py +0 -0
  34. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/participant_token.py +0 -0
  35. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/participant_token_test.py +0 -0
  36. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/port_forward.py +0 -0
  37. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/port_forward_test.py +0 -0
  38. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/protocol.py +0 -0
  39. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/protocol_test.py +0 -0
  40. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/py.typed +0 -0
  41. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/reasoning_schema.py +0 -0
  42. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/registry_auth.py +0 -0
  43. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/room_ports.py +0 -0
  44. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/room_server_client.py +0 -0
  45. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/room_server_client_test.py +0 -0
  46. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/runtime.py +0 -0
  47. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/runtime_test.py +0 -0
  48. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/schema.py +0 -0
  49. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/schema_document.py +0 -0
  50. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/schema_document_test.py +0 -0
  51. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/schema_registry.py +0 -0
  52. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/schema_test.py +0 -0
  53. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/schema_util.py +0 -0
  54. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/service_spec_test.py +0 -0
  55. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/service_template_test.py +0 -0
  56. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/services.py +0 -0
  57. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/services_test.py +0 -0
  58. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/specs/service.py +0 -0
  59. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/sql.py +0 -0
  60. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/sql_test.py +0 -0
  61. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/sqlite_transfer.py +0 -0
  62. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/sqlite_transfer_test.py +0 -0
  63. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/token_test.py +0 -0
  64. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/urls.py +0 -0
  65. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/webhooks.py +0 -0
  66. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/webhooks_test.py +0 -0
  67. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/websocket_protocol.py +0 -0
  68. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/websocket_protocol_test.py +0 -0
  69. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent_api.egg-info/SOURCES.txt +0 -0
  70. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent_api.egg-info/dependency_links.txt +0 -0
  71. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent_api.egg-info/requires.txt +0 -0
  72. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent_api.egg-info/top_level.txt +0 -0
  73. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/pyproject.toml +0 -0
  74. {meshagent_api-0.52.4 → meshagent_api-0.53.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshagent-api
3
- Version: 0.52.4
3
+ Version: 0.53.0
4
4
  Summary: Python Server API for Meshagent
5
5
  License-Expression: Apache-2.0
6
6
  Project-URL: Documentation, https://docs.meshagent.com
@@ -265,6 +265,7 @@ ProjectRole = Literal[
265
265
  "usage_reporter",
266
266
  "billing_manager",
267
267
  "group_manager",
268
+ "user_profile_editor",
268
269
  ]
269
270
  ResourceRole = Literal["viewer", "operator", "developer", "admin"]
270
271
  CustomDomainRole = Literal["viewer", "user", "admin"]
@@ -708,6 +709,17 @@ class User(BaseModel):
708
709
  first_name: Optional[str] = None
709
710
  last_name: Optional[str] = None
710
711
  email: str
712
+ metadata: dict[str, JsonValue] = Field(default_factory=dict)
713
+ annotations: dict[str, str] = Field(default_factory=dict)
714
+
715
+
716
+ class UpdateUserProfileRequest(BaseModel):
717
+ model_config = ConfigDict(extra="forbid", strict=True)
718
+
719
+ first_name: str | None = None
720
+ last_name: str | None = None
721
+ metadata: dict[str, JsonValue] = Field(default_factory=dict)
722
+ annotations: dict[str, str] = Field(default_factory=dict)
711
723
 
712
724
 
713
725
  class UserRoomGrant(BaseModel):
@@ -1584,15 +1596,34 @@ class Meshagent:
1584
1596
  return await resp.json()
1585
1597
 
1586
1598
  async def update_user_profile(
1587
- self, user_id: str, first_name: str, last_name: str
1599
+ self,
1600
+ user_id: str,
1601
+ first_name: str | None = None,
1602
+ last_name: str | None = None,
1603
+ *,
1604
+ metadata: dict[str, JsonValue] | None = None,
1605
+ annotations: dict[str, str] | None = None,
1606
+ project_id: str | None = None,
1588
1607
  ) -> Dict[str, Any]:
1589
1608
  """
1590
1609
  Corresponds to: PUT /accounts/profiles/:id
1591
- Body: { "first_name", "last_name" }
1610
+ Omitted fields are preserved; metadata and annotations replace their maps.
1611
+ Editing another user or annotations requires the user_profile_editor role
1612
+ in project_id, and the target must belong to that project.
1592
1613
  Returns a JSON dict with { "ok": True } on success.
1593
1614
  """
1594
1615
  url = f"{self.base_url}/accounts/profiles/{user_id}"
1595
- body = {"first_name": first_name, "last_name": last_name}
1616
+ body: dict[str, Any] = {}
1617
+ if first_name is not None:
1618
+ body["first_name"] = first_name
1619
+ if last_name is not None:
1620
+ body["last_name"] = last_name
1621
+ if metadata is not None:
1622
+ body["metadata"] = metadata
1623
+ if annotations is not None:
1624
+ body["annotations"] = annotations
1625
+ if project_id is not None:
1626
+ url += f"?project_id={quote(project_id, safe='')}"
1596
1627
 
1597
1628
  async with self._session.put(
1598
1629
  url, headers=self._get_headers(), json=body
@@ -20,6 +20,8 @@ from meshagent.api.client import (
20
20
  Meshagent,
21
21
  Room,
22
22
  RoomDisabledError,
23
+ UpdateUserProfileRequest,
24
+ User,
23
25
  room_scope_for_role_compat,
24
26
  )
25
27
  from meshagent.api.specs.service import (
@@ -2738,3 +2740,55 @@ async def test_access_evaluator_methods_use_access_routes():
2738
2740
  {"subject": {"type": "user", "id": "user-1"}},
2739
2741
  ),
2740
2742
  ]
2743
+
2744
+
2745
+ @pytest.mark.asyncio
2746
+ async def test_update_user_profile_supports_partial_metadata_and_editor_context():
2747
+ session = _FakeSession(
2748
+ [
2749
+ _FakeResponse(status=200, payload={"ok": True}),
2750
+ _FakeResponse(status=200, payload={"ok": True}),
2751
+ ]
2752
+ )
2753
+ client = Meshagent(base_url="http://example.test", token="token", session=session)
2754
+ await client.update_user_profile("me", metadata={})
2755
+ await client.update_user_profile(
2756
+ "user-2",
2757
+ "Grace",
2758
+ "Hopper",
2759
+ metadata={"theme": "dark"},
2760
+ annotations={"department": "research"},
2761
+ project_id="project-1",
2762
+ )
2763
+ assert session.calls == [
2764
+ ("put", "http://example.test/accounts/profiles/me", {"metadata": {}}),
2765
+ (
2766
+ "put",
2767
+ "http://example.test/accounts/profiles/user-2?project_id=project-1",
2768
+ {
2769
+ "first_name": "Grace",
2770
+ "last_name": "Hopper",
2771
+ "metadata": {"theme": "dark"},
2772
+ "annotations": {"department": "research"},
2773
+ },
2774
+ ),
2775
+ ]
2776
+
2777
+
2778
+ def test_user_profile_models_preserve_json_metadata_and_string_annotations():
2779
+ user = User.model_validate(
2780
+ {
2781
+ "id": "user-1",
2782
+ "email": "ada@example.test",
2783
+ "metadata": {"nested": {"numbers": [1, 2]}, "active": True},
2784
+ "annotations": {"department": "engineering"},
2785
+ }
2786
+ )
2787
+ assert user.model_dump()["metadata"] == {
2788
+ "nested": {"numbers": [1, 2]},
2789
+ "active": True,
2790
+ }
2791
+ assert user.annotations == {"department": "engineering"}
2792
+ assert User(id="old-user", email="old@example.test").metadata == {}
2793
+ update = UpdateUserProfileRequest.model_validate({"metadata": {}})
2794
+ assert update.model_dump(exclude_unset=True) == {"metadata": {}}
@@ -0,0 +1 @@
1
+ __version__ = "0.53.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshagent-api
3
- Version: 0.52.4
3
+ Version: 0.53.0
4
4
  Summary: Python Server API for Meshagent
5
5
  License-Expression: Apache-2.0
6
6
  Project-URL: Documentation, https://docs.meshagent.com
@@ -1 +0,0 @@
1
- __version__ = "0.52.4"
File without changes
File without changes
File without changes