imperal-sdk 4.2.6__tar.gz → 4.2.8__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 (206) hide show
  1. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/CHANGELOG.md +113 -0
  2. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/PKG-INFO +1 -1
  3. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/__init__.py +1 -1
  4. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/context.py +41 -1
  5. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/manifest_schema.py +28 -0
  6. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/.github/workflows/identity-contract.yml +0 -0
  7. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/.github/workflows/publish.yml +0 -0
  8. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/.github/workflows/test.yml +0 -0
  9. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/.gitignore +0 -0
  10. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/LICENSE +0 -0
  11. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/README.md +0 -0
  12. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/api_surface.json +0 -0
  13. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/pyproject.toml +0 -0
  14. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/.codebase-index-cache.pkl +0 -0
  15. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/ai/__init__.py +0 -0
  16. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/ai/client.py +0 -0
  17. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/auth/__init__.py +0 -0
  18. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/auth/client.py +0 -0
  19. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/auth/middleware.py +0 -0
  20. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/billing/__init__.py +0 -0
  21. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/billing/client.py +0 -0
  22. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/cache/__init__.py +0 -0
  23. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/cache/client.py +0 -0
  24. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/cache/protocol.py +0 -0
  25. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/chat/__init__.py +0 -0
  26. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/chat/action_result.py +0 -0
  27. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/chat/error_codes.py +0 -0
  28. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/chat/extension.py +0 -0
  29. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/chat/filters.py +0 -0
  30. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/chat/guards.py +0 -0
  31. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/chat/handler.py +0 -0
  32. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/chat/kernel_primitives.py +0 -0
  33. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/chat/narration.py +0 -0
  34. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/chat/narration_guard.py +0 -0
  35. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/chat/prompt.py +0 -0
  36. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/chat/refusal.py +0 -0
  37. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/chat/retry.py +0 -0
  38. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/cli/__init__.py +0 -0
  39. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/cli/main.py +0 -0
  40. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/config/__init__.py +0 -0
  41. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/config/client.py +0 -0
  42. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/db/__init__.py +0 -0
  43. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/db/client.py +0 -0
  44. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/errors.py +0 -0
  45. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/extension.py +0 -0
  46. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/extensions/__init__.py +0 -0
  47. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/extensions/client.py +0 -0
  48. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/http/__init__.py +0 -0
  49. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/http/client.py +0 -0
  50. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/manifest.py +0 -0
  51. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/notify/__init__.py +0 -0
  52. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/notify/client.py +0 -0
  53. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/prompts/__init__.py +0 -0
  54. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/prompts/icnli_integrity_rules.txt +0 -0
  55. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/prompts/kernel_formatting_rule.txt +0 -0
  56. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/prompts/kernel_proactivity_rule.txt +0 -0
  57. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/protocols.py +0 -0
  58. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/rpc/__init__.py +0 -0
  59. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/rpc/codec.py +0 -0
  60. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/rpc/contract.py +0 -0
  61. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/runtime/__init__.py +0 -0
  62. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/runtime/executor.py +0 -0
  63. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/runtime/llm_provider.py +0 -0
  64. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/runtime/message_adapter.py +0 -0
  65. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/schemas/action_result.schema.json +0 -0
  66. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/schemas/balance_info.schema.json +0 -0
  67. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/schemas/chat_result.schema.json +0 -0
  68. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/schemas/completion_result.schema.json +0 -0
  69. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/schemas/document.schema.json +0 -0
  70. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/schemas/event.schema.json +0 -0
  71. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/schemas/file_info.schema.json +0 -0
  72. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/schemas/function_call.schema.json +0 -0
  73. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/schemas/http_response.schema.json +0 -0
  74. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/schemas/imperal.schema.json +0 -0
  75. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/schemas/limits_result.schema.json +0 -0
  76. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/schemas/subscription_info.schema.json +0 -0
  77. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/secrets/__init__.py +0 -0
  78. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/secrets/client.py +0 -0
  79. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/secrets/exceptions.py +0 -0
  80. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/secrets/panel_handler.py +0 -0
  81. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/secrets/spec.py +0 -0
  82. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/security/__init__.py +0 -0
  83. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/security/call_token.py +0 -0
  84. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/skeleton/__init__.py +0 -0
  85. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/skeleton/client.py +0 -0
  86. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/storage/__init__.py +0 -0
  87. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/storage/client.py +0 -0
  88. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/store/__init__.py +0 -0
  89. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/store/client.py +0 -0
  90. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/store/exceptions.py +0 -0
  91. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/testing/__init__.py +0 -0
  92. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/testing/mock_context.py +0 -0
  93. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/testing/mock_secrets.py +0 -0
  94. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/tools/__init__.py +0 -0
  95. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/tools/client.py +0 -0
  96. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/tools/generate_api_surface.py +0 -0
  97. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/tools/validate_identity_contract.py +0 -0
  98. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/types/__init__.py +0 -0
  99. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/types/action_result.py +0 -0
  100. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/types/chat_result.py +0 -0
  101. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/types/client_contracts.py +0 -0
  102. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/types/contracts.py +0 -0
  103. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/types/contributions.py +0 -0
  104. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/types/events.py +0 -0
  105. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/types/health.py +0 -0
  106. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/types/identity.py +0 -0
  107. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/types/models.py +0 -0
  108. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/types/pagination.py +0 -0
  109. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/types/store_contracts.py +0 -0
  110. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/ui/__init__.py +0 -0
  111. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/ui/actions.py +0 -0
  112. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/ui/base.py +0 -0
  113. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/ui/data.py +0 -0
  114. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/ui/display.py +0 -0
  115. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/ui/feedback.py +0 -0
  116. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/ui/graph.py +0 -0
  117. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/ui/input_components.py +0 -0
  118. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/ui/interactive.py +0 -0
  119. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/ui/layout.py +0 -0
  120. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/ui/theme.py +0 -0
  121. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/validator.py +0 -0
  122. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/src/imperal_sdk/validator_v1_6_0.py +0 -0
  123. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/conftest.py +0 -0
  124. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/contracts/__init__.py +0 -0
  125. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/contracts/test_store_contracts.py +0 -0
  126. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/fixtures/openapi/auth-gateway.json +0 -0
  127. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/fixtures/openapi/registry.json +0 -0
  128. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/fixtures/openapi/sharelock-cases.json +0 -0
  129. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/rpc/__init__.py +0 -0
  130. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/rpc/test_codec.py +0 -0
  131. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/rpc/test_contract.py +0 -0
  132. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/runtime/__init__.py +0 -0
  133. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/runtime/test_llm_provider_config_store.py +0 -0
  134. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/runtime/test_llm_provider_ctx_injection.py +0 -0
  135. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/store/__init__.py +0 -0
  136. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/store/test_list_users_client.py +0 -0
  137. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/store/test_query_all_client.py +0 -0
  138. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_action_result_typed.py +0 -0
  139. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_as_user.py +0 -0
  140. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_auth.py +0 -0
  141. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_billing.py +0 -0
  142. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_cache_client.py +0 -0
  143. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_cache_model.py +0 -0
  144. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_call_token.py +0 -0
  145. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_chat_extension_deprecation.py +0 -0
  146. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_chat_filters.py +0 -0
  147. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_chat_guards.py +0 -0
  148. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_chat_guards_bleed.py +0 -0
  149. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_chat_prompt.py +0 -0
  150. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_chat_pydantic_retry.py +0 -0
  151. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_chat_result.py +0 -0
  152. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_cli.py +0 -0
  153. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_client_contracts.py +0 -0
  154. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_config_client.py +0 -0
  155. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_context.py +0 -0
  156. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_context_guards.py +0 -0
  157. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_contracts.py +0 -0
  158. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_contracts_live.py +0 -0
  159. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_contributions.py +0 -0
  160. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_document_contract.py +0 -0
  161. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_emits_decorator.py +0 -0
  162. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_error_codes.py +0 -0
  163. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_errors.py +0 -0
  164. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_event_schema_v2.py +0 -0
  165. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_events_health.py +0 -0
  166. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_extension.py +0 -0
  167. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_extension_v2.py +0 -0
  168. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_extensions_emit.py +0 -0
  169. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_handler_p2.py +0 -0
  170. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_id_shape_guard.py +0 -0
  171. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_identity_contract.py +0 -0
  172. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_imperal_schema_v2.py +0 -0
  173. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_kernel_primitives.py +0 -0
  174. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_manifest.py +0 -0
  175. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_manifest_roundtrip_gate.py +0 -0
  176. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_manifest_schema.py +0 -0
  177. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_manifest_v2_events.py +0 -0
  178. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_manifest_v2_other_sections.py +0 -0
  179. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_manifest_v2_webhooks.py +0 -0
  180. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_manifest_validator_v2.py +0 -0
  181. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_mock_context.py +0 -0
  182. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_models.py +0 -0
  183. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_narration_emission.py +0 -0
  184. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_narration_guard.py +0 -0
  185. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_openai_max_completion_tokens.py +0 -0
  186. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_pagination.py +0 -0
  187. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_panel_rendering_contract.py +0 -0
  188. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_panels.py +0 -0
  189. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_skeleton_decorator.py +0 -0
  190. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_spec_validation.py +0 -0
  191. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_tools_client.py +0 -0
  192. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_ui.py +0 -0
  193. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_ui_fileupload_enhanced.py +0 -0
  194. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_ui_html.py +0 -0
  195. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_ui_image_enhanced.py +0 -0
  196. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_ui_open.py +0 -0
  197. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_ui_theme.py +0 -0
  198. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_user.py +0 -0
  199. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_v7_emit_refusal.py +0 -0
  200. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_validator.py +0 -0
  201. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_validator_drift.py +0 -0
  202. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_validator_pep563.py +0 -0
  203. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_validator_v1_6_0_rules.py +0 -0
  204. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/test_write_arg_bleed.py +0 -0
  205. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/tools/__init__.py +0 -0
  206. {imperal_sdk-4.2.6 → imperal_sdk-4.2.8}/tests/tools/test_generate_api_surface.py +0 -0
@@ -2,6 +2,119 @@
2
2
 
3
3
  All notable changes to `imperal-sdk` are documented here.
4
4
 
5
+ ## 4.2.8 — 2026-05-13
6
+
7
+ **Fix: `secrets[]` finally in `Manifest` Pydantic schema**
8
+
9
+ EXT-SECRETS-V1 manifest emitter has been writing `manifest["secrets"] = [...]`
10
+ since v4.2.2, but the `Manifest` Pydantic model in `manifest_schema.py` had
11
+ no matching field. With `model_config = ConfigDict(extra="forbid")`, this
12
+ should have caused `validate_manifest_dict()` to reject every manifest that
13
+ declared secrets — but publish-time validators didn't gate through this
14
+ schema, so the drift lived silently for six PATCH releases.
15
+
16
+ ### Added
17
+
18
+ - **`SecretDecl` Pydantic model** in `manifest_schema.py` — mirrors
19
+ `imperal_sdk.secrets.spec.SecretSpec.to_manifest_dict()`. Validates
20
+ `name` regex (`^[a-z][a-z0-9_]{0,62}$`), `write_mode` in
21
+ `{user, extension, both}`, `max_bytes` in `[1, 65536]`,
22
+ `rotation_hint_days >= 1` when present, non-empty `description`.
23
+ - **`Manifest.secrets: Optional[List[SecretDecl]]`** field — additive,
24
+ back-compatible with manifests that don't declare any secrets.
25
+
26
+ ### Federal invariants
27
+
28
+ | Invariant | What it pins |
29
+ |---|---|
30
+ | `I-MANIFEST-EMITTER-SCHEMA-SYMMETRIC` | (already declared in v4.1.6 canary roundtrip test) Now actually holds for `secrets[]` — emitter and schema agree. |
31
+
32
+ ### Migration notes
33
+
34
+ - **No code change required** in any extension. Existing manifests with
35
+ `secrets[]` (emitted since v4.2.2) now pass strict Pydantic validation
36
+ instead of relying on validators that didn't gate through the schema.
37
+ - Manifests with malformed secret entries (e.g. `name` with uppercase or
38
+ invalid `write_mode`) will now fail `validate_manifest_dict()` at
39
+ publish time. Previously they slipped through.
40
+
41
+ ## 4.2.7 — 2026-05-13
42
+
43
+ **OAuth callback infrastructure + `ctx.webhook_url()` helper**
44
+
45
+ Closes the architectural gap that made `@ext.webhook("/callback", method="GET")`
46
+ non-functional for OAuth providers (Spotify, GitHub, Google). Before this
47
+ release: hardcoded redirect URIs in `*_config.py` landed users on a Next.js
48
+ 404 (no nginx route for `/v1/ext/*`), and even if they reached auth-gw the
49
+ `ext_router` was POST-only.
50
+
51
+ ### Added
52
+
53
+ - **`Context.webhook_url(path)`** — builds the canonical public callback
54
+ URL from kernel-authoritative `_extension_id` (folder/manifest name, not
55
+ the drift-prone Python `Extension("X", ...)` value). Returns
56
+ `https://{IMPERAL_PUBLIC_HOST}/v1/ext/{app_id}/webhook/{path}` — default
57
+ host `panel.imperal.io`. Path leading slash is normalised. Use this
58
+ instead of hardcoding the URL in config files; hardcoded URLs are the
59
+ #1 cause of OAuth-callback drift bugs.
60
+
61
+ - **Federal `ctx.secrets` inject moved to `ContextFactory._build_context`** —
62
+ every dispatch path (chat tool, panel, skeleton, schedule, webhook,
63
+ lifecycle, health check) now gets `ctx.secrets` uniformly. Previously
64
+ the inject lived in `pipeline/extension_runner.py` and only fired for
65
+ chat tool dispatch; panel handlers and others crashed with
66
+ `AttributeError` when reading `ctx.secrets` despite the documented
67
+ federal contract. `_HealthCheckCtx` gained a `_StubSecrets` graceful
68
+ no-op so `@ext.health_check` handlers that read `ctx.secrets` don't
69
+ crash with `AttributeError`.
70
+
71
+ - **Kernel-authoritative `app_id` in `ctx.cache`** — `CacheClient` is now
72
+ constructed with `self._extension_id` (kernel parameter) instead of
73
+ `getattr(self._extension, "app_id", ...)` (Python runtime). Fixes the
74
+ 401 class observed in production when an ext author writes
75
+ `Extension("X-extension", ...)` while the deployed folder/manifest is
76
+ `X` — auth-gw extcache row uses the deployed app_id and would never
77
+ authorise the drifted Python value.
78
+
79
+ ### Platform changes (live, not in the package)
80
+
81
+ - **nginx** on `panel.imperal.io` now routes `/v1/ext/*` to Imperal Auth
82
+ Gateway (was: caught by Next.js catch-all → 404). Renamed config from
83
+ `sharelock-panel*` → `imperal-panel`.
84
+ - **Auth-gw `ext_router`** accepts both `GET` (OAuth callbacks,
85
+ verification challenges) and `POST` (server-to-server hooks) on the
86
+ same `/v1/ext/{app_id}/webhook/{path}` endpoint.
87
+ - **Auth-gw `marketplace/router.py`** new public endpoint
88
+ `GET /v1/marketplace/apps/{app_id}/webhooks` returns `[{path, method}]`
89
+ for each declared `@ext.webhook`. Strips `secret_header`.
90
+ - **Imperal Panel** Secrets tab renders a blue info card listing every
91
+ webhook URL with Copy buttons so end-users know what to paste into
92
+ OAuth provider developer consoles.
93
+ - **Dev Portal App Details** gained a Webhooks tab (`imperal-ext-developer`
94
+ v1.3.0) showing the per-app callback URLs with method badges.
95
+
96
+ ### Migration notes
97
+
98
+ - Replace `SP_REDIRECT_URI = "https://..."` hardcodes with
99
+ `ctx.webhook_url("/callback")` at runtime. Existing hardcoded URLs that
100
+ match the canonical shape keep working — but new extensions should
101
+ prefer the helper. No SDK-blocking change in this release.
102
+ - `@ext.health_check` handlers that call `await ctx.secrets.list()` /
103
+ `.get(...)` now receive a graceful no-op stub instead of
104
+ `AttributeError`. Reads return `None`/`[]`/`False`; writes raise
105
+ `RuntimeError` (health checks have no per-user context).
106
+ - All shadow patches applied on 2026-05-13 to platform-worker and
107
+ session-worker venvs are superseded by this release. Run
108
+ `pip install --upgrade imperal-sdk==4.2.7` to clear them.
109
+
110
+ ### Federal invariants
111
+
112
+ | Invariant | What it pins |
113
+ |---|---|
114
+ | `I-SECRETS-HANDLER-SCOPE-MEMORY` | Already pinned; the ContextFactory move preserves it — plaintext stays a local variable in the handler call. |
115
+ | `I-EXT-CACHE-APP-ID-KERNEL-AUTHORITATIVE` | (new) `CacheClient.app_id` sourced from kernel `_extension_id`, never from Python `ext.app_id`. |
116
+ | `I-WEBHOOK-URL-CANONICAL` | (new) `ctx.webhook_url(path)` returns `https://{IMPERAL_PUBLIC_HOST}/v1/ext/{kernel-authoritative-app_id}/webhook/{path}`. Source-inspection-friendly: env var lookup + no Python-instance attribute drift. |
117
+
5
118
  ## 4.2.6 — 2026-05-13
6
119
 
7
120
  **New: `ui.Password` primitive + `ui.Input(type=)` kwarg**
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: imperal-sdk
3
- Version: 4.2.6
3
+ Version: 4.2.8
4
4
  Summary: SDK for building Imperal Cloud extensions
5
5
  Author: Valentin Scerbacov, Imperal, Inc.
6
6
  License-Expression: AGPL-3.0-or-later
@@ -39,7 +39,7 @@ from imperal_sdk.secrets import (
39
39
  SecretValueTooLarge, SecretDeclarationConflict,
40
40
  )
41
41
 
42
- __version__ = "4.2.6"
42
+ __version__ = "4.2.8"
43
43
 
44
44
  __all__ = [
45
45
  # Core
@@ -218,7 +218,14 @@ class Context:
218
218
  try:
219
219
  from imperal_sdk.cache.client import CacheClient
220
220
  self._cache = CacheClient(
221
- app_id=getattr(self._extension, "app_id", self._extension_id),
221
+ # 2026-05-13: kernel-authoritative app_id (folder/manifest
222
+ # name passed by ContextFactory). ext.app_id is the Python
223
+ # runtime value and can drift from the deployed app_id
224
+ # (e.g. Extension("spotify-extension") in app.py while
225
+ # /opt/extensions/spotify/ + Dev Portal row are "spotify"
226
+ # — auth-gw extcache 401'd every request). Fall back to
227
+ # ext.app_id only when factory didn't pass _extension_id.
228
+ app_id=self._extension_id or getattr(self._extension, "app_id", ""),
222
229
  user_id=self.user.imperal_id,
223
230
  gw_url=gw,
224
231
  service_token=svc,
@@ -289,6 +296,39 @@ class Context:
289
296
  logger = logging.getLogger(f"ext.{self._extension_id}")
290
297
  getattr(logger, level, logger.info)(message)
291
298
 
299
+ def webhook_url(self, path: str) -> str:
300
+ """Build the public OAuth/webhook callback URL for this extension.
301
+
302
+ Returns the URL the extension author must register in the OAuth
303
+ provider's developer console (Spotify, GitHub, Google, etc.).
304
+
305
+ Path is the same string passed to ``@ext.webhook("/path")``. Both
306
+ forms work — leading slash is normalised:
307
+
308
+ ctx.webhook_url("/callback") # → .../webhook/callback
309
+ ctx.webhook_url("callback") # → .../webhook/callback
310
+ ctx.webhook_url("/oauth/return") # → .../webhook/oauth/return
311
+
312
+ Host comes from the ``IMPERAL_PUBLIC_HOST`` env var (default
313
+ ``panel.imperal.io``). Path-component ``{app_id}`` comes from the
314
+ kernel-authoritative ``_extension_id`` (folder/manifest name),
315
+ not from ``ext.app_id`` (Python runtime, can drift).
316
+
317
+ Use this instead of hardcoding the URL in ``spotify_config.py``
318
+ et al. — that pattern is what caused the 2026-05-13 Spotify 401
319
+ class (auth-gw never saw the drifted `spotify-extension` row).
320
+ """
321
+ import os as _os_wh
322
+ host = _os_wh.environ.get("IMPERAL_PUBLIC_HOST", "panel.imperal.io")
323
+ clean_path = (path or "").lstrip("/")
324
+ app_id = self._extension_id or getattr(self._extension, "app_id", "")
325
+ if not app_id:
326
+ raise RuntimeError(
327
+ "ctx.webhook_url() called without an extension_id — "
328
+ "kernel must build ctx via ContextFactory."
329
+ )
330
+ return f"https://{host}/v1/ext/{app_id}/webhook/{clean_path}"
331
+
292
332
  def as_user(self, user_id: str) -> "Context":
293
333
  """Return scoped Context for target user_id.
294
334
 
@@ -240,6 +240,26 @@ class TrayDecl(BaseModel):
240
240
  tooltip: Optional[str] = None
241
241
 
242
242
 
243
+ class SecretDecl(BaseModel):
244
+ """One entry in `manifest['secrets']` — EXT-SECRETS-V1 (v4.2.2+).
245
+
246
+ Mirrors :class:`imperal_sdk.secrets.spec.SecretSpec` after
247
+ ``to_manifest_dict()``. The Pydantic model exists so
248
+ :func:`validate_manifest_dict` round-trips the emitted shape — closes
249
+ the `I-MANIFEST-EMITTER-SCHEMA-SYMMETRIC` drift gap that lived
250
+ silently from v4.2.2 → v4.2.7.
251
+ """
252
+
253
+ model_config = ConfigDict(extra="forbid")
254
+
255
+ name: str = Field(..., pattern=r"^[a-z][a-z0-9_]{0,62}$")
256
+ description: str = Field(..., min_length=1)
257
+ required: bool = False
258
+ write_mode: Literal["user", "extension", "both"] = "user"
259
+ max_bytes: int = Field(default=4096, ge=1, le=65536)
260
+ rotation_hint_days: Optional[int] = Field(default=None, ge=1)
261
+
262
+
243
263
  # === Root model =======================================================
244
264
 
245
265
  class Manifest(BaseModel):
@@ -290,6 +310,14 @@ class Manifest(BaseModel):
290
310
  # Reserved for first-party Imperal authors (validator V31).
291
311
  system: Optional[bool] = None
292
312
 
313
+ # Federal v4.2.2 — EXT-SECRETS-V1. Optional array of per-user encrypted
314
+ # credential declarations the extension reads via ``ctx.secrets.get()``.
315
+ # Closes the `I-MANIFEST-EMITTER-SCHEMA-SYMMETRIC` drift where the
316
+ # emitter wrote `secrets[]` from v4.2.2 onwards but this Pydantic model
317
+ # had no matching field (extra="forbid" would have rejected — but
318
+ # publish-time validators didn't gate through here).
319
+ secrets: Optional[List[SecretDecl]] = None
320
+
293
321
  # --- Marketplace merge (docs/imperal-cloud/developer-portal.md) ---
294
322
  name: Optional[str] = None
295
323
  description: Optional[str] = None
File without changes
File without changes
File without changes
File without changes