imperal-sdk 5.2.0__tar.gz → 5.2.1__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 (277) hide show
  1. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/CHANGELOG.md +25 -7
  2. imperal_sdk-5.2.1/PKG-INFO +148 -0
  3. imperal_sdk-5.2.1/README.md +111 -0
  4. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/__init__.py +1 -1
  5. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/chat/extension.py +14 -15
  6. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_manifest_no_orchestrator_tool.py +29 -12
  7. imperal_sdk-5.2.0/PKG-INFO +0 -264
  8. imperal_sdk-5.2.0/README.md +0 -227
  9. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/.github/workflows/identity-contract.yml +0 -0
  10. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/.github/workflows/publish.yml +0 -0
  11. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/.github/workflows/test.yml +0 -0
  12. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/.gitignore +0 -0
  13. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/LICENSE +0 -0
  14. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/api_surface.json +0 -0
  15. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/docs/sdl-facets.md +0 -0
  16. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/pyproject.toml +0 -0
  17. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/sdk_claims.json +0 -0
  18. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/sdl_roles.json +0 -0
  19. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/.codebase-index-cache.pkl +0 -0
  20. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/ai/__init__.py +0 -0
  21. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/ai/client.py +0 -0
  22. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/auth/__init__.py +0 -0
  23. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/auth/client.py +0 -0
  24. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/auth/middleware.py +0 -0
  25. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/billing/__init__.py +0 -0
  26. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/billing/client.py +0 -0
  27. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/cache/__init__.py +0 -0
  28. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/cache/client.py +0 -0
  29. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/cache/protocol.py +0 -0
  30. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/chat/__init__.py +0 -0
  31. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/chat/action_result.py +0 -0
  32. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/chat/error_codes.py +0 -0
  33. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/chat/exceptions.py +0 -0
  34. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/chat/filters.py +0 -0
  35. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/chat/guards.py +0 -0
  36. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/chat/kernel_primitives.py +0 -0
  37. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/chat/narration.py +0 -0
  38. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/chat/narration_guard.py +0 -0
  39. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/chat/prompt.py +0 -0
  40. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/chat/refusal.py +0 -0
  41. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/cli/__init__.py +0 -0
  42. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/cli/main.py +0 -0
  43. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/config/__init__.py +0 -0
  44. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/config/client.py +0 -0
  45. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/context.py +0 -0
  46. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/devtools/__init__.py +0 -0
  47. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/devtools/contract_checks.py +0 -0
  48. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/devtools/generate_api_surface.py +0 -0
  49. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/devtools/generate_sdk_claims.py +0 -0
  50. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/devtools/validate_identity_contract.py +0 -0
  51. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/errors.py +0 -0
  52. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/extension.py +0 -0
  53. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/extensions/__init__.py +0 -0
  54. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/extensions/client.py +0 -0
  55. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/http/__init__.py +0 -0
  56. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/http/client.py +0 -0
  57. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/manifest.py +0 -0
  58. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/manifest_schema.py +0 -0
  59. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/notify/__init__.py +0 -0
  60. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/notify/client.py +0 -0
  61. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/prompts/__init__.py +0 -0
  62. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/prompts/icnli_integrity_rules.txt +0 -0
  63. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/prompts/kernel_formatting_rule.txt +0 -0
  64. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/prompts/kernel_proactivity_rule.txt +0 -0
  65. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/protocols.py +0 -0
  66. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/rpc/__init__.py +0 -0
  67. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/rpc/codec.py +0 -0
  68. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/rpc/contract.py +0 -0
  69. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/runtime/__init__.py +0 -0
  70. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/runtime/executor.py +0 -0
  71. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/runtime/llm_provider.py +0 -0
  72. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/runtime/message_adapter.py +0 -0
  73. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/schemas/action_result.schema.json +0 -0
  74. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/schemas/balance_info.schema.json +0 -0
  75. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/schemas/chat_result.schema.json +0 -0
  76. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/schemas/completion_result.schema.json +0 -0
  77. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/schemas/document.schema.json +0 -0
  78. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/schemas/event.schema.json +0 -0
  79. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/schemas/file_info.schema.json +0 -0
  80. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/schemas/function_call.schema.json +0 -0
  81. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/schemas/http_response.schema.json +0 -0
  82. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/schemas/imperal.schema.json +0 -0
  83. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/schemas/limits_result.schema.json +0 -0
  84. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/schemas/subscription_info.schema.json +0 -0
  85. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/__init__.py +0 -0
  86. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/_generate_roles_json.py +0 -0
  87. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/entity.py +0 -0
  88. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/__init__.py +0 -0
  89. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/catalog.py +0 -0
  90. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/comm.py +0 -0
  91. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/content.py +0 -0
  92. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/device.py +0 -0
  93. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/event.py +0 -0
  94. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/geo.py +0 -0
  95. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/identity.py +0 -0
  96. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/media.py +0 -0
  97. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/metric.py +0 -0
  98. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/money.py +0 -0
  99. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/net.py +0 -0
  100. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/people.py +0 -0
  101. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/quantity.py +0 -0
  102. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/rating.py +0 -0
  103. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/security.py +0 -0
  104. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/task.py +0 -0
  105. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/facets/time.py +0 -0
  106. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/field.py +0 -0
  107. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/sdl/roles.py +0 -0
  108. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/secrets/__init__.py +0 -0
  109. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/secrets/client.py +0 -0
  110. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/secrets/exceptions.py +0 -0
  111. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/secrets/panel_handler.py +0 -0
  112. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/secrets/spec.py +0 -0
  113. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/security/__init__.py +0 -0
  114. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/security/call_token.py +0 -0
  115. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/skeleton/__init__.py +0 -0
  116. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/skeleton/client.py +0 -0
  117. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/storage/__init__.py +0 -0
  118. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/storage/client.py +0 -0
  119. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/store/__init__.py +0 -0
  120. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/store/client.py +0 -0
  121. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/store/exceptions.py +0 -0
  122. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/testing/__init__.py +0 -0
  123. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/testing/mock_context.py +0 -0
  124. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/testing/mock_secrets.py +0 -0
  125. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/types/__init__.py +0 -0
  126. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/types/action_result.py +0 -0
  127. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/types/chat_result.py +0 -0
  128. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/types/client_contracts.py +0 -0
  129. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/types/contracts.py +0 -0
  130. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/types/contributions.py +0 -0
  131. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/types/events.py +0 -0
  132. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/types/health.py +0 -0
  133. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/types/identity.py +0 -0
  134. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/types/models.py +0 -0
  135. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/types/pagination.py +0 -0
  136. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/types/store_contracts.py +0 -0
  137. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/ui/__init__.py +0 -0
  138. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/ui/actions.py +0 -0
  139. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/ui/base.py +0 -0
  140. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/ui/data.py +0 -0
  141. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/ui/display.py +0 -0
  142. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/ui/feedback.py +0 -0
  143. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/ui/graph.py +0 -0
  144. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/ui/input_components.py +0 -0
  145. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/ui/interactive.py +0 -0
  146. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/ui/layout.py +0 -0
  147. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/ui/theme.py +0 -0
  148. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/validator.py +0 -0
  149. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/src/imperal_sdk/validator_v1_6_0.py +0 -0
  150. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/conftest.py +0 -0
  151. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/contract/__init__.py +0 -0
  152. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/contract/test_contract_checks_selftest.py +0 -0
  153. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/contract/test_generate_sdk_claims.py +0 -0
  154. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/contract/test_sample_contract_shape.py +0 -0
  155. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/contract/test_sdk_matches_kernel_contract.py +0 -0
  156. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/contracts/__init__.py +0 -0
  157. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/contracts/test_store_contracts.py +0 -0
  158. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/fixtures/contract/kernel-contract.sample.json +0 -0
  159. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/fixtures/openapi/auth-gateway.json +0 -0
  160. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/fixtures/openapi/registry.json +0 -0
  161. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/fixtures/openapi/sharelock-cases.json +0 -0
  162. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/rpc/__init__.py +0 -0
  163. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/rpc/test_codec.py +0 -0
  164. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/rpc/test_contract.py +0 -0
  165. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/runtime/__init__.py +0 -0
  166. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/runtime/test_llm_provider_config_store.py +0 -0
  167. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/runtime/test_llm_provider_ctx_injection.py +0 -0
  168. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/store/__init__.py +0 -0
  169. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/store/test_list_users_client.py +0 -0
  170. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/store/test_query_all_client.py +0 -0
  171. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_action_result_typed.py +0 -0
  172. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_as_user.py +0 -0
  173. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_auth.py +0 -0
  174. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_billing.py +0 -0
  175. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_cache_client.py +0 -0
  176. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_cache_model.py +0 -0
  177. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_call_token.py +0 -0
  178. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_chat_extension_deprecation.py +0 -0
  179. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_chat_extension_no_llm_router.py +0 -0
  180. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_chat_filters.py +0 -0
  181. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_chat_function_background_flag.py +0 -0
  182. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_chat_guards.py +0 -0
  183. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_chat_guards_bleed.py +0 -0
  184. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_chat_prompt.py +0 -0
  185. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_chat_result.py +0 -0
  186. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_cli.py +0 -0
  187. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_client_contracts.py +0 -0
  188. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_config_client.py +0 -0
  189. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_context.py +0 -0
  190. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_context_background_task.py +0 -0
  191. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_context_deliver_chat_message.py +0 -0
  192. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_context_guards.py +0 -0
  193. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_contracts.py +0 -0
  194. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_contracts_live.py +0 -0
  195. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_contributions.py +0 -0
  196. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_data_model_kwarg.py +0 -0
  197. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_document_contract.py +0 -0
  198. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_emits_decorator.py +0 -0
  199. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_error_codes.py +0 -0
  200. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_errors.py +0 -0
  201. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_event_schema_v2.py +0 -0
  202. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_events_health.py +0 -0
  203. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_extension.py +0 -0
  204. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_extension_v2.py +0 -0
  205. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_extensions_emit.py +0 -0
  206. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_http_timeout_override.py +0 -0
  207. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_id_shape_guard.py +0 -0
  208. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_identity_contract.py +0 -0
  209. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_imperal_schema_v2.py +0 -0
  210. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_kernel_primitives.py +0 -0
  211. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_manifest.py +0 -0
  212. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_manifest_roundtrip_gate.py +0 -0
  213. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_manifest_schema.py +0 -0
  214. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_manifest_v2_events.py +0 -0
  215. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_manifest_v2_other_sections.py +0 -0
  216. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_manifest_v2_webhooks.py +0 -0
  217. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_manifest_validator_v2.py +0 -0
  218. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_mock_context.py +0 -0
  219. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_models.py +0 -0
  220. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_narration_emission.py +0 -0
  221. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_narration_guard.py +0 -0
  222. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_openai_max_completion_tokens.py +0 -0
  223. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_pagination.py +0 -0
  224. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_panel_rendering_contract.py +0 -0
  225. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_panels.py +0 -0
  226. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_phase_a_dead_removal.py +0 -0
  227. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_phase_a_drift.py +0 -0
  228. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_phase_a_text.py +0 -0
  229. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdk_version_stamp.py +0 -0
  230. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_entity.py +0 -0
  231. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_entity_marker.py +0 -0
  232. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_exports.py +0 -0
  233. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_catalog.py +0 -0
  234. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_collisions.py +0 -0
  235. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_comm.py +0 -0
  236. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_content.py +0 -0
  237. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_device.py +0 -0
  238. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_event.py +0 -0
  239. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_exports.py +0 -0
  240. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_field.py +0 -0
  241. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_geo.py +0 -0
  242. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_identity.py +0 -0
  243. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_media.py +0 -0
  244. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_metric.py +0 -0
  245. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_money.py +0 -0
  246. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_net.py +0 -0
  247. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_people.py +0 -0
  248. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_quantity.py +0 -0
  249. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_rating.py +0 -0
  250. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_security.py +0 -0
  251. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_task.py +0 -0
  252. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facet_time.py +0 -0
  253. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facets_catalog.py +0 -0
  254. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facets_doc.py +0 -0
  255. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_facets_pkg.py +0 -0
  256. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_field.py +0 -0
  257. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_roles.py +0 -0
  258. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_roles_json.py +0 -0
  259. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_sdl_roles_of_facets.py +0 -0
  260. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_skeleton_decorator.py +0 -0
  261. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_spec_validation.py +0 -0
  262. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_ui.py +0 -0
  263. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_ui_fileupload_enhanced.py +0 -0
  264. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_ui_html.py +0 -0
  265. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_ui_image_enhanced.py +0 -0
  266. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_ui_open.py +0 -0
  267. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_ui_theme.py +0 -0
  268. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_user.py +0 -0
  269. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_v7_emit_refusal.py +0 -0
  270. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_validator.py +0 -0
  271. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_validator_drift.py +0 -0
  272. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_validator_pep563.py +0 -0
  273. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_validator_v1_6_0_rules.py +0 -0
  274. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_validator_v25.py +0 -0
  275. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/test_write_arg_bleed.py +0 -0
  276. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/tools/__init__.py +0 -0
  277. {imperal_sdk-5.2.0 → imperal_sdk-5.2.1}/tests/tools/test_generate_api_surface.py +0 -0
@@ -2,14 +2,33 @@
2
2
 
3
3
  All notable changes to `imperal-sdk` are documented here.
4
4
 
5
+ ## 5.2.1 — 2026-06-01 — ChatExtension ergonomics & honest deprecations
6
+
7
+ Small, fully backward-compatible cleanup of `ChatExtension`. No API removals;
8
+ existing extensions are unaffected.
9
+
10
+ ### Changed
11
+
12
+ - `ChatExtension(tool_name=...)` no longer emits a `DeprecationWarning`. The
13
+ kwarg is the **canonical** chat-registration key — it groups your
14
+ `@chat.function` tools in the manifest, anchors the per-turn prompt, and
15
+ labels scope-guard audit lines. It is load-bearing and not going away; the
16
+ prior "removed in 5.1.0" warning was incorrect and has been removed.
17
+
18
+ ### Added
19
+
20
+ - `ChatExtension(...)` now accepts an **optional** `tool_name`. When omitted it
21
+ defaults to `f"tool_{ext.app_id}_chat"`. Pass it explicitly to pin a stable
22
+ routing name (recommended for production extensions). `description=` is now
23
+ optional as well.
24
+
5
25
  ## 5.2.0 — 2026-05-31 — Structured Data Layer (SDL) foundation
6
26
 
7
27
  Introduces the **SDL (`imperal_sdk.sdl`)** — a typed, semantic vocabulary for the
8
28
  data an extension returns, so the platform can read an entity's id / title / kind
9
29
  and its facets directly instead of inferring them from field names. This release
10
30
  ships the SDK foundation (canonical types + the standard facet library + a schema
11
- marker for platform detection); the platform begins reading SDL behind a rollout
12
- flag in a later release. Fully **additive** — the existing API and existing
31
+ marker for platform detection). **The platform reads SDL in production today.** Fully **additive** — the existing API and existing
13
32
  extensions are unchanged; adopting SDL is opt-in via `data_model=`.
14
33
 
15
34
  ### Added
@@ -28,8 +47,8 @@ extensions are unchanged; adopting SDL is opt-in via `data_model=`.
28
47
  - `sdl.roles_of(model)` — introspect a model's field→role map.
29
48
 
30
49
  Use it via `data_model=` on `@chat.function` (e.g.
31
- `class Note(sdl.Entity): ...` → `data_model=Note`). Full platform integration
32
- arrives in a later phase. Not yet wired into the platform.
50
+ `class Note(sdl.Entity): ...` → `data_model=Note`). **The platform reads SDL
51
+ entities in production today.**
33
52
  - **SDL — Standard Facet Library (Phase 2).** 123 composable facet mixins across
34
53
  17 families (Identity, Time, People, Content, Communication, Media, Quantities,
35
54
  Money, Catalog, Tasks, Location, Tech/Network, Analytics, Events, Ratings,
@@ -43,9 +62,8 @@ extensions are unchanged; adopting SDL is opt-in via `data_model=`.
43
62
 
44
63
  564 standard roles are catalogued in `sdl_roles.json`. Every facet field is
45
64
  optional; for anything not covered, use `sdl.field(role="yourapp.x")` with a
46
- non-reserved namespace. Full guide: `docs/sdl-facets.md`. Still not wired into
47
- the platform — extensions can adopt the types now; the platform begins reading
48
- them in a later phase.
65
+ non-reserved namespace. Full guide: `docs/sdl-facets.md`. **Live in production**
66
+ extensions adopt the types and the platform reads them today.
49
67
  - **SDL — schema marker on `Entity` / `EntityList`.** Both stamp
50
68
  `x-sdl: "entity"` / `"entity-list"` into their JSON schema so the platform can
51
69
  detect an SDL-typed result from a function's return schema alone. Inherited by
@@ -0,0 +1,148 @@
1
+ Metadata-Version: 2.4
2
+ Name: imperal-sdk
3
+ Version: 5.2.1
4
+ Summary: SDK for building Imperal Cloud extensions
5
+ Author: Valentin Scerbacov, Imperal, Inc.
6
+ License-Expression: AGPL-3.0-or-later
7
+ License-File: LICENSE
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Framework :: FastAPI
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Classifier: Typing :: Typed
18
+ Requires-Python: >=3.11
19
+ Requires-Dist: click>=8.1.0
20
+ Requires-Dist: httpx>=0.28.0
21
+ Requires-Dist: pydantic>=2.10.0
22
+ Requires-Dist: pyjwt[crypto]>=2.10.0
23
+ Provides-Extra: contract
24
+ Requires-Dist: schemathesis>=3.30.0; extra == 'contract'
25
+ Provides-Extra: db
26
+ Requires-Dist: aiomysql>=0.2.0; extra == 'db'
27
+ Requires-Dist: sqlalchemy[asyncio]>=2.0.30; extra == 'db'
28
+ Provides-Extra: dev
29
+ Requires-Dist: jsonschema>=4.21.0; extra == 'dev'
30
+ Requires-Dist: openapi-spec-validator>=0.7.1; extra == 'dev'
31
+ Requires-Dist: pytest-asyncio>=0.25.0; extra == 'dev'
32
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
33
+ Requires-Dist: respx>=0.22.0; extra == 'dev'
34
+ Provides-Extra: fastapi
35
+ Requires-Dist: fastapi>=0.115.0; extra == 'fastapi'
36
+ Description-Content-Type: text/markdown
37
+
38
+ <div align="center">
39
+
40
+ # Imperal SDK
41
+
42
+ ### Build extensions for Webbee 🐝 — the agent of Imperal Cloud, the world's first AI Cloud OS.
43
+
44
+ **Write a small Python function. Webbee calls it when a user asks for it — in their own words. Ship it to the Marketplace and get paid.**
45
+
46
+ [![PyPI](https://img.shields.io/pypi/v/imperal-sdk?color=blue&label=PyPI)](https://pypi.org/project/imperal-sdk/)
47
+ [![Python](https://img.shields.io/pypi/pyversions/imperal-sdk)](https://pypi.org/project/imperal-sdk/)
48
+ [![License](https://img.shields.io/badge/license-AGPL--3.0-blue)](LICENSE)
49
+
50
+ [Documentation](https://docs.imperal.io) · [Quickstart](https://docs.imperal.io/en/getting-started/quick-start/) · [PyPI](https://pypi.org/project/imperal-sdk/) · [imperal.io](https://imperal.io)
51
+
52
+ </div>
53
+
54
+ ---
55
+
56
+ ## What this is
57
+
58
+ **Imperal Cloud** is the world's first AI Cloud OS — a cloud you connect the contexts of your life into (mail, money, projects, servers, notes, anything) and then run entirely in your own native language. **Webbee 🐝** is the AI agent that lives inside it and does the work for you, safely.
59
+
60
+ **The Imperal SDK is how you give Webbee a new skill.** You write a small, typed Python *extension*; Webbee picks it up and calls it whenever a user asks for what it does — in plain language. The platform handles the hard parts — authentication, billing, multi-tenancy, audit, recovery, LLM routing — so your code stays small.
61
+
62
+ ```bash
63
+ pip install imperal-sdk
64
+ ```
65
+
66
+ > Python 3.11+ · AGPL-3.0-or-later
67
+
68
+ ## Why build here
69
+
70
+ - **Webbee calls your function directly.** Typed, structured calls — no LLM guessing your arguments, no silent write failures.
71
+ - **The platform does the plumbing.** Auth, per-user isolation, billing, audit, retries and recovery, multi-tenant safety — handled for you.
72
+ - **You get paid.** Publish to the Imperal Marketplace, price your extension, earn on every use.
73
+ - **Bring any LLM.** Users connect their own model keys — Anthropic, OpenAI, Google, Ollama, any OpenAI-compatible API.
74
+
75
+ ## A 60-second extension
76
+
77
+ ```python
78
+ from imperal_sdk import Extension, ChatExtension, ActionResult
79
+ from pydantic import BaseModel, Field
80
+
81
+ ext = Extension(
82
+ "hello-world",
83
+ version="1.0.0",
84
+ display_name="Hello World",
85
+ description="Greets people by name with a friendly message.",
86
+ icon="icon.svg",
87
+ actions_explicit=True,
88
+ )
89
+
90
+ chat = ChatExtension(ext, tool_name="hello_world", description="Friendly greetings.")
91
+
92
+
93
+ class GreetParams(BaseModel):
94
+ name: str = Field(..., description="Person to greet")
95
+
96
+
97
+ @chat.function("greet", description="Greet someone by name.", action_type="read")
98
+ async def greet(ctx, params: GreetParams) -> ActionResult:
99
+ return ActionResult.success(
100
+ data={"message": f"Hello, {params.name}! 🐝"},
101
+ summary=f"Greeted {params.name}",
102
+ )
103
+ ```
104
+
105
+ That's a real, working extension. When a user types *"say hi to Alex"*, Webbee calls `greet(name="Alex")`.
106
+
107
+ → Full walkthrough, from zero to published: **[docs.imperal.io](https://docs.imperal.io/en/getting-started/quick-start/)**
108
+
109
+ ## What you can build
110
+
111
+ - **Chat tools** — typed `@chat.function`s Webbee calls straight from natural language.
112
+ - **Panels** — UI surfaces rendered inside the Imperal Panel.
113
+ - **Skeletons** — live data feeds that keep Webbee aware of a user's state.
114
+ - **Scheduled jobs & webhooks** — act on a timer, or react to outside events.
115
+ - **Typed entities (SDL)** — return `sdl.Entity` objects and the platform reads their meaning (id, title, kind, …) directly instead of guessing field names. Live in production.
116
+
117
+ Every published extension passes the **federal contract** — the validators that let Webbee call your code safely. The SDK checks it locally before you ship.
118
+
119
+ ## Test without a server
120
+
121
+ ```python
122
+ from imperal_sdk.testing import MockContext
123
+
124
+ async def test_greet():
125
+ ctx = MockContext()
126
+ result = await greet(ctx, GreetParams(name="Alex"))
127
+ assert result.status == "success"
128
+ ```
129
+
130
+ ## Documentation
131
+
132
+ The full API, the manifest schema, every validator, recipes, and the federal contract live at **[docs.imperal.io](https://docs.imperal.io)** — that's the source of truth; this README is just the doorway.
133
+
134
+ | | |
135
+ |---|---|
136
+ | Documentation | [docs.imperal.io](https://docs.imperal.io) |
137
+ | Quickstart | [docs.imperal.io/en/getting-started/quick-start](https://docs.imperal.io/en/getting-started/quick-start/) |
138
+ | PyPI | [pypi.org/project/imperal-sdk](https://pypi.org/project/imperal-sdk/) |
139
+ | Changelog | [CHANGELOG.md](CHANGELOG.md) |
140
+ | License | [AGPL-3.0-or-later](LICENSE) |
141
+
142
+ ---
143
+
144
+ <div align="center">
145
+
146
+ **Built by [Imperal, Inc.](https://imperal.io) — Webbee 🐝 is its agent.**
147
+
148
+ </div>
@@ -0,0 +1,111 @@
1
+ <div align="center">
2
+
3
+ # Imperal SDK
4
+
5
+ ### Build extensions for Webbee 🐝 — the agent of Imperal Cloud, the world's first AI Cloud OS.
6
+
7
+ **Write a small Python function. Webbee calls it when a user asks for it — in their own words. Ship it to the Marketplace and get paid.**
8
+
9
+ [![PyPI](https://img.shields.io/pypi/v/imperal-sdk?color=blue&label=PyPI)](https://pypi.org/project/imperal-sdk/)
10
+ [![Python](https://img.shields.io/pypi/pyversions/imperal-sdk)](https://pypi.org/project/imperal-sdk/)
11
+ [![License](https://img.shields.io/badge/license-AGPL--3.0-blue)](LICENSE)
12
+
13
+ [Documentation](https://docs.imperal.io) · [Quickstart](https://docs.imperal.io/en/getting-started/quick-start/) · [PyPI](https://pypi.org/project/imperal-sdk/) · [imperal.io](https://imperal.io)
14
+
15
+ </div>
16
+
17
+ ---
18
+
19
+ ## What this is
20
+
21
+ **Imperal Cloud** is the world's first AI Cloud OS — a cloud you connect the contexts of your life into (mail, money, projects, servers, notes, anything) and then run entirely in your own native language. **Webbee 🐝** is the AI agent that lives inside it and does the work for you, safely.
22
+
23
+ **The Imperal SDK is how you give Webbee a new skill.** You write a small, typed Python *extension*; Webbee picks it up and calls it whenever a user asks for what it does — in plain language. The platform handles the hard parts — authentication, billing, multi-tenancy, audit, recovery, LLM routing — so your code stays small.
24
+
25
+ ```bash
26
+ pip install imperal-sdk
27
+ ```
28
+
29
+ > Python 3.11+ · AGPL-3.0-or-later
30
+
31
+ ## Why build here
32
+
33
+ - **Webbee calls your function directly.** Typed, structured calls — no LLM guessing your arguments, no silent write failures.
34
+ - **The platform does the plumbing.** Auth, per-user isolation, billing, audit, retries and recovery, multi-tenant safety — handled for you.
35
+ - **You get paid.** Publish to the Imperal Marketplace, price your extension, earn on every use.
36
+ - **Bring any LLM.** Users connect their own model keys — Anthropic, OpenAI, Google, Ollama, any OpenAI-compatible API.
37
+
38
+ ## A 60-second extension
39
+
40
+ ```python
41
+ from imperal_sdk import Extension, ChatExtension, ActionResult
42
+ from pydantic import BaseModel, Field
43
+
44
+ ext = Extension(
45
+ "hello-world",
46
+ version="1.0.0",
47
+ display_name="Hello World",
48
+ description="Greets people by name with a friendly message.",
49
+ icon="icon.svg",
50
+ actions_explicit=True,
51
+ )
52
+
53
+ chat = ChatExtension(ext, tool_name="hello_world", description="Friendly greetings.")
54
+
55
+
56
+ class GreetParams(BaseModel):
57
+ name: str = Field(..., description="Person to greet")
58
+
59
+
60
+ @chat.function("greet", description="Greet someone by name.", action_type="read")
61
+ async def greet(ctx, params: GreetParams) -> ActionResult:
62
+ return ActionResult.success(
63
+ data={"message": f"Hello, {params.name}! 🐝"},
64
+ summary=f"Greeted {params.name}",
65
+ )
66
+ ```
67
+
68
+ That's a real, working extension. When a user types *"say hi to Alex"*, Webbee calls `greet(name="Alex")`.
69
+
70
+ → Full walkthrough, from zero to published: **[docs.imperal.io](https://docs.imperal.io/en/getting-started/quick-start/)**
71
+
72
+ ## What you can build
73
+
74
+ - **Chat tools** — typed `@chat.function`s Webbee calls straight from natural language.
75
+ - **Panels** — UI surfaces rendered inside the Imperal Panel.
76
+ - **Skeletons** — live data feeds that keep Webbee aware of a user's state.
77
+ - **Scheduled jobs & webhooks** — act on a timer, or react to outside events.
78
+ - **Typed entities (SDL)** — return `sdl.Entity` objects and the platform reads their meaning (id, title, kind, …) directly instead of guessing field names. Live in production.
79
+
80
+ Every published extension passes the **federal contract** — the validators that let Webbee call your code safely. The SDK checks it locally before you ship.
81
+
82
+ ## Test without a server
83
+
84
+ ```python
85
+ from imperal_sdk.testing import MockContext
86
+
87
+ async def test_greet():
88
+ ctx = MockContext()
89
+ result = await greet(ctx, GreetParams(name="Alex"))
90
+ assert result.status == "success"
91
+ ```
92
+
93
+ ## Documentation
94
+
95
+ The full API, the manifest schema, every validator, recipes, and the federal contract live at **[docs.imperal.io](https://docs.imperal.io)** — that's the source of truth; this README is just the doorway.
96
+
97
+ | | |
98
+ |---|---|
99
+ | Documentation | [docs.imperal.io](https://docs.imperal.io) |
100
+ | Quickstart | [docs.imperal.io/en/getting-started/quick-start](https://docs.imperal.io/en/getting-started/quick-start/) |
101
+ | PyPI | [pypi.org/project/imperal-sdk](https://pypi.org/project/imperal-sdk/) |
102
+ | Changelog | [CHANGELOG.md](CHANGELOG.md) |
103
+ | License | [AGPL-3.0-or-later](LICENSE) |
104
+
105
+ ---
106
+
107
+ <div align="center">
108
+
109
+ **Built by [Imperal, Inc.](https://imperal.io) — Webbee 🐝 is its agent.**
110
+
111
+ </div>
@@ -40,7 +40,7 @@ from imperal_sdk.secrets import (
40
40
  SecretValueTooLarge, SecretDeclarationConflict,
41
41
  )
42
42
 
43
- __version__ = "5.2.0"
43
+ __version__ = "5.2.1"
44
44
 
45
45
  __all__ = [
46
46
  # Core
@@ -64,9 +64,16 @@ class FunctionDef:
64
64
 
65
65
 
66
66
  class ChatExtension:
67
- def __init__(self, ext, tool_name: str, description: str, system_prompt: str = "",
67
+ def __init__(self, ext, tool_name: str | None = None, description: str = "",
68
+ system_prompt: str = "",
68
69
  model: "str | None" = None, max_rounds: int = 10):
69
70
  self.ext = ext
71
+ # tool_name is the canonical chat-registration key: it groups the
72
+ # extension's @chat.function tools in the manifest, anchors the per-turn
73
+ # system prompt, and labels scope-guard audit lines. Optional — derived
74
+ # from the extension app_id (``tool_<app_id>_chat``) when omitted; pass
75
+ # it explicitly to pin a production-stable routing name.
76
+ tool_name = tool_name or f"tool_{ext.app_id}_chat"
70
77
  self.tool_name = tool_name
71
78
  self.description = description
72
79
  self.system_prompt = system_prompt
@@ -94,20 +101,12 @@ class ChatExtension:
94
101
  "Example: 'Notes module — manage user notes and folders.'"
95
102
  )
96
103
 
97
- # v5.0.0: orchestrator-tool auto-registration REMOVED. ChatExtension
98
- # is now purely a @chat.function bundle declaration the platform
99
- # chain executor dispatches each function directly via typed dispatch.
100
- # tool_name kwarg retained for back-compat but emits DeprecationWarning.
101
- # Will be removed in 5.1.0.
102
- import warnings as _warnings
103
- _warnings.warn(
104
- f"ChatExtension(tool_name={tool_name!r}): kwarg deprecated in SDK 5.0.0 "
105
- "(orchestrator-tool auto-registration removed). Move classifier-readable "
106
- "text into Extension(description=...) + per-@chat.function(description=...). "
107
- "Will be removed in 5.1.0.",
108
- DeprecationWarning,
109
- stacklevel=2,
110
- )
104
+ # v5.0.0 removed orchestrator-tool auto-registration: ChatExtension is
105
+ # purely a @chat.function bundle declaration, and the platform chain
106
+ # executor dispatches each function directly via typed dispatch — the
107
+ # host LLM no longer sees a single ``tool_<app_id>_chat`` umbrella tool.
108
+ # ``tool_name`` is retained as the canonical registration key (see the
109
+ # __init__ note above) — it is NOT deprecated.
111
110
  ext._chat_extensions = getattr(ext, "_chat_extensions", {})
112
111
  ext._chat_extensions[tool_name] = self
113
112
 
@@ -8,10 +8,7 @@ from imperal_sdk.chat import ChatExtension
8
8
  def test_chat_extension_does_not_emit_orchestrator_tool():
9
9
  """Building a manifest from an ext with a ChatExtension must not include tool_<name>_chat."""
10
10
  ext = Extension(app_id="demo", description="demo ext for emitter test")
11
- # Suppress the DeprecationWarning emitted by ChatExtension(tool_name=...) — covered separately.
12
- with warnings.catch_warnings():
13
- warnings.simplefilter("ignore", DeprecationWarning)
14
- chat = ChatExtension(ext, tool_name="demo_legacy_kwarg", description="legacy")
11
+ chat = ChatExtension(ext, tool_name="demo_legacy_kwarg", description="legacy")
15
12
 
16
13
  @chat.function(name="list_items", description="list user items for the demo ext")
17
14
  async def list_items(ctx):
@@ -53,17 +50,37 @@ def test_chat_extension_does_not_emit_orchestrator_tool():
53
50
  )
54
51
 
55
52
 
56
- def test_chat_extension_tool_name_kwarg_emits_deprecation_warning():
57
- """ChatExtension(tool_name=...) must emit DeprecationWarning at construction."""
53
+ def test_chat_extension_tool_name_kwarg_does_not_warn():
54
+ """ChatExtension(tool_name=...) is the canonical chat-registration key — it
55
+ must NOT emit a DeprecationWarning.
56
+
57
+ Reversed from the transient SDK 5.0.0 stance: the kwarg is load-bearing
58
+ (manifest grouping key + per-turn prompt + scope guards), has no
59
+ replacement API, and every first-party extension passes it. A deprecation
60
+ warning with no migration path is cry-wolf noise, so it was removed.
61
+ """
58
62
  ext = Extension(app_id="demo2", description="demo ext for deprecation test")
59
63
  with warnings.catch_warnings(record=True) as caught:
60
64
  warnings.simplefilter("always")
61
65
  ChatExtension(ext, tool_name="legacy_name", description="legacy")
62
- deprecation = [w for w in caught if issubclass(w.category, DeprecationWarning)]
63
- assert deprecation, (
64
- "ChatExtension(tool_name=...) MUST emit a DeprecationWarning in SDK 5.0.0"
66
+ tool_name_deprecations = [
67
+ w for w in caught
68
+ if issubclass(w.category, DeprecationWarning) and "tool_name" in str(w.message)
69
+ ]
70
+ assert not tool_name_deprecations, (
71
+ "ChatExtension(tool_name=...) must NOT emit a tool_name DeprecationWarning; "
72
+ f"got: {[str(w.message) for w in tool_name_deprecations]}"
73
+ )
74
+
75
+
76
+ def test_chat_extension_tool_name_optional_defaults_to_app_id():
77
+ """tool_name is optional — when omitted it derives from the extension app_id
78
+ (``tool_<app_id>_chat``) and is used as the manifest registration key."""
79
+ ext = Extension(app_id="demo3", description="demo ext for default-tool-name test")
80
+ chat = ChatExtension(ext, description="no explicit tool_name")
81
+ assert chat.tool_name == "tool_demo3_chat", (
82
+ f"omitted tool_name must default to tool_<app_id>_chat; got {chat.tool_name!r}"
65
83
  )
66
- msg = str(deprecation[0].message)
67
- assert "tool_name" in msg and ("5.0.0" in msg or "5.1.0" in msg), (
68
- f"DeprecationWarning message must reference tool_name and version cutoff; got: {msg}"
84
+ assert "tool_demo3_chat" in ext._chat_extensions, (
85
+ "default tool_name must be registered as the _chat_extensions key"
69
86
  )