imperal-sdk 4.2.12__tar.gz → 4.2.14__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 (210) hide show
  1. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/CHANGELOG.md +83 -18
  2. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/PKG-INFO +1 -1
  3. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/__init__.py +1 -1
  4. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/chat/extension.py +11 -1
  5. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/chat/handler.py +30 -1
  6. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/manifest.py +2 -0
  7. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/manifest_schema.py +6 -0
  8. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/schemas/imperal.schema.json +26 -2
  9. imperal_sdk-4.2.14/tests/test_chat_function_background_flag.py +154 -0
  10. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/.github/workflows/identity-contract.yml +0 -0
  11. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/.github/workflows/publish.yml +0 -0
  12. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/.github/workflows/test.yml +0 -0
  13. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/.gitignore +0 -0
  14. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/LICENSE +0 -0
  15. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/README.md +0 -0
  16. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/api_surface.json +0 -0
  17. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/pyproject.toml +0 -0
  18. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/.codebase-index-cache.pkl +0 -0
  19. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/ai/__init__.py +0 -0
  20. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/ai/client.py +0 -0
  21. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/auth/__init__.py +0 -0
  22. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/auth/client.py +0 -0
  23. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/auth/middleware.py +0 -0
  24. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/billing/__init__.py +0 -0
  25. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/billing/client.py +0 -0
  26. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/cache/__init__.py +0 -0
  27. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/cache/client.py +0 -0
  28. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/cache/protocol.py +0 -0
  29. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/chat/__init__.py +0 -0
  30. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/chat/action_result.py +0 -0
  31. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/chat/error_codes.py +0 -0
  32. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/chat/filters.py +0 -0
  33. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/chat/guards.py +0 -0
  34. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/chat/kernel_primitives.py +0 -0
  35. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/chat/narration.py +0 -0
  36. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/chat/narration_guard.py +0 -0
  37. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/chat/prompt.py +0 -0
  38. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/chat/refusal.py +0 -0
  39. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/chat/retry.py +0 -0
  40. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/cli/__init__.py +0 -0
  41. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/cli/main.py +0 -0
  42. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/config/__init__.py +0 -0
  43. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/config/client.py +0 -0
  44. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/context.py +0 -0
  45. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/db/__init__.py +0 -0
  46. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/db/client.py +0 -0
  47. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/errors.py +0 -0
  48. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/extension.py +0 -0
  49. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/extensions/__init__.py +0 -0
  50. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/extensions/client.py +0 -0
  51. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/http/__init__.py +0 -0
  52. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/http/client.py +0 -0
  53. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/notify/__init__.py +0 -0
  54. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/notify/client.py +0 -0
  55. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/prompts/__init__.py +0 -0
  56. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/prompts/icnli_integrity_rules.txt +0 -0
  57. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/prompts/kernel_formatting_rule.txt +0 -0
  58. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/prompts/kernel_proactivity_rule.txt +0 -0
  59. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/protocols.py +0 -0
  60. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/rpc/__init__.py +0 -0
  61. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/rpc/codec.py +0 -0
  62. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/rpc/contract.py +0 -0
  63. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/runtime/__init__.py +0 -0
  64. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/runtime/executor.py +0 -0
  65. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/runtime/llm_provider.py +0 -0
  66. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/runtime/message_adapter.py +0 -0
  67. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/schemas/action_result.schema.json +0 -0
  68. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/schemas/balance_info.schema.json +0 -0
  69. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/schemas/chat_result.schema.json +0 -0
  70. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/schemas/completion_result.schema.json +0 -0
  71. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/schemas/document.schema.json +0 -0
  72. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/schemas/event.schema.json +0 -0
  73. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/schemas/file_info.schema.json +0 -0
  74. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/schemas/function_call.schema.json +0 -0
  75. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/schemas/http_response.schema.json +0 -0
  76. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/schemas/limits_result.schema.json +0 -0
  77. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/schemas/subscription_info.schema.json +0 -0
  78. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/secrets/__init__.py +0 -0
  79. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/secrets/client.py +0 -0
  80. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/secrets/exceptions.py +0 -0
  81. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/secrets/panel_handler.py +0 -0
  82. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/secrets/spec.py +0 -0
  83. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/security/__init__.py +0 -0
  84. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/security/call_token.py +0 -0
  85. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/skeleton/__init__.py +0 -0
  86. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/skeleton/client.py +0 -0
  87. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/storage/__init__.py +0 -0
  88. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/storage/client.py +0 -0
  89. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/store/__init__.py +0 -0
  90. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/store/client.py +0 -0
  91. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/store/exceptions.py +0 -0
  92. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/testing/__init__.py +0 -0
  93. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/testing/mock_context.py +0 -0
  94. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/testing/mock_secrets.py +0 -0
  95. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/tools/__init__.py +0 -0
  96. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/tools/client.py +0 -0
  97. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/tools/generate_api_surface.py +0 -0
  98. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/tools/validate_identity_contract.py +0 -0
  99. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/types/__init__.py +0 -0
  100. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/types/action_result.py +0 -0
  101. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/types/chat_result.py +0 -0
  102. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/types/client_contracts.py +0 -0
  103. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/types/contracts.py +0 -0
  104. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/types/contributions.py +0 -0
  105. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/types/events.py +0 -0
  106. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/types/health.py +0 -0
  107. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/types/identity.py +0 -0
  108. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/types/models.py +0 -0
  109. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/types/pagination.py +0 -0
  110. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/types/store_contracts.py +0 -0
  111. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/ui/__init__.py +0 -0
  112. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/ui/actions.py +0 -0
  113. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/ui/base.py +0 -0
  114. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/ui/data.py +0 -0
  115. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/ui/display.py +0 -0
  116. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/ui/feedback.py +0 -0
  117. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/ui/graph.py +0 -0
  118. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/ui/input_components.py +0 -0
  119. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/ui/interactive.py +0 -0
  120. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/ui/layout.py +0 -0
  121. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/ui/theme.py +0 -0
  122. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/validator.py +0 -0
  123. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/src/imperal_sdk/validator_v1_6_0.py +0 -0
  124. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/conftest.py +0 -0
  125. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/contracts/__init__.py +0 -0
  126. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/contracts/test_store_contracts.py +0 -0
  127. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/fixtures/openapi/auth-gateway.json +0 -0
  128. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/fixtures/openapi/registry.json +0 -0
  129. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/fixtures/openapi/sharelock-cases.json +0 -0
  130. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/rpc/__init__.py +0 -0
  131. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/rpc/test_codec.py +0 -0
  132. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/rpc/test_contract.py +0 -0
  133. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/runtime/__init__.py +0 -0
  134. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/runtime/test_llm_provider_config_store.py +0 -0
  135. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/runtime/test_llm_provider_ctx_injection.py +0 -0
  136. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/store/__init__.py +0 -0
  137. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/store/test_list_users_client.py +0 -0
  138. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/store/test_query_all_client.py +0 -0
  139. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_action_result_typed.py +0 -0
  140. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_as_user.py +0 -0
  141. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_auth.py +0 -0
  142. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_billing.py +0 -0
  143. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_cache_client.py +0 -0
  144. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_cache_model.py +0 -0
  145. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_call_token.py +0 -0
  146. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_chat_extension_deprecation.py +0 -0
  147. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_chat_filters.py +0 -0
  148. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_chat_guards.py +0 -0
  149. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_chat_guards_bleed.py +0 -0
  150. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_chat_prompt.py +0 -0
  151. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_chat_pydantic_retry.py +0 -0
  152. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_chat_result.py +0 -0
  153. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_cli.py +0 -0
  154. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_client_contracts.py +0 -0
  155. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_config_client.py +0 -0
  156. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_context.py +0 -0
  157. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_context_background_task.py +0 -0
  158. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_context_deliver_chat_message.py +0 -0
  159. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_context_guards.py +0 -0
  160. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_contracts.py +0 -0
  161. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_contracts_live.py +0 -0
  162. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_contributions.py +0 -0
  163. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_document_contract.py +0 -0
  164. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_emits_decorator.py +0 -0
  165. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_error_codes.py +0 -0
  166. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_errors.py +0 -0
  167. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_event_schema_v2.py +0 -0
  168. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_events_health.py +0 -0
  169. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_extension.py +0 -0
  170. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_extension_v2.py +0 -0
  171. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_extensions_emit.py +0 -0
  172. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_handler_p2.py +0 -0
  173. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_http_timeout_override.py +0 -0
  174. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_id_shape_guard.py +0 -0
  175. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_identity_contract.py +0 -0
  176. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_imperal_schema_v2.py +0 -0
  177. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_kernel_primitives.py +0 -0
  178. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_manifest.py +0 -0
  179. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_manifest_roundtrip_gate.py +0 -0
  180. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_manifest_schema.py +0 -0
  181. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_manifest_v2_events.py +0 -0
  182. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_manifest_v2_other_sections.py +0 -0
  183. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_manifest_v2_webhooks.py +0 -0
  184. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_manifest_validator_v2.py +0 -0
  185. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_mock_context.py +0 -0
  186. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_models.py +0 -0
  187. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_narration_emission.py +0 -0
  188. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_narration_guard.py +0 -0
  189. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_openai_max_completion_tokens.py +0 -0
  190. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_pagination.py +0 -0
  191. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_panel_rendering_contract.py +0 -0
  192. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_panels.py +0 -0
  193. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_skeleton_decorator.py +0 -0
  194. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_spec_validation.py +0 -0
  195. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_tools_client.py +0 -0
  196. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_ui.py +0 -0
  197. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_ui_fileupload_enhanced.py +0 -0
  198. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_ui_html.py +0 -0
  199. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_ui_image_enhanced.py +0 -0
  200. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_ui_open.py +0 -0
  201. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_ui_theme.py +0 -0
  202. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_user.py +0 -0
  203. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_v7_emit_refusal.py +0 -0
  204. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_validator.py +0 -0
  205. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_validator_drift.py +0 -0
  206. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_validator_pep563.py +0 -0
  207. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_validator_v1_6_0_rules.py +0 -0
  208. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/test_write_arg_bleed.py +0 -0
  209. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/tools/__init__.py +0 -0
  210. {imperal_sdk-4.2.12 → imperal_sdk-4.2.14}/tests/tools/test_generate_api_surface.py +0 -0
@@ -2,6 +2,77 @@
2
2
 
3
3
  All notable changes to `imperal-sdk` are documented here.
4
4
 
5
+ ## 4.2.14 — 2026-05-14
6
+
7
+ **Fix: regenerate static `imperal.schema.json` to match runtime `Manifest` model**
8
+
9
+ v4.2.13 added `background` + `long_running` to the `Tool` Pydantic model
10
+ in `manifest_schema.py` but forgot to regenerate the committed
11
+ `src/imperal_sdk/schemas/imperal.schema.json` static mirror. The CI
12
+ gate `test_static_schema_file_in_sync` caught the drift on the v4.2.13
13
+ release commit (same pattern as the v4.2.8 → v4.2.9 fix).
14
+
15
+ ### Fixed
16
+
17
+ - Regenerated `src/imperal_sdk/schemas/imperal.schema.json` from runtime
18
+ `manifest_schema.get_schema()`. Static artifact equals runtime model
19
+ again.
20
+
21
+ No public API change. Single-file fix paired with v4.2.13.
22
+
23
+ ## 4.2.13 — 2026-05-14
24
+
25
+ **Feat: `@chat.function(background=True)` declarative flag**
26
+
27
+ Sugar over `ctx.background_task(coro, ...)` from v4.2.12 — author writes
28
+ one handler body, the SDK auto-wraps the call in `ctx.background_task()`
29
+ when the flag is set.
30
+
31
+ ### Added
32
+
33
+ - **`@chat.function(..., background=True, long_running=False)`** — when
34
+ `background=True`, the SDK chat handler wraps the function call in
35
+ `ctx.background_task()` instead of running the handler synchronously.
36
+ The LLM receives an immediate ack envelope carrying `task_id`; the
37
+ platform delivers the handler's returned `ActionResult` as a fresh
38
+ bot turn when the work finishes. `long_running=True` raises the
39
+ federal 180-second cap to 1800 seconds.
40
+
41
+ ```python
42
+ @chat.function(
43
+ "refine_output",
44
+ description="Refine the given text via AI completion.",
45
+ action_type="write",
46
+ event="text_refined",
47
+ background=True, # auto-wrap in ctx.background_task
48
+ long_running=False, # default cap 180s; True → 1800s
49
+ )
50
+ async def refine_output(ctx, params: RefineParams) -> ActionResult:
51
+ # Body runs detached. No inner _work() wrapper, no manual task_id.
52
+ await ctx.progress(50, "Generating with AI")
53
+ resp = await ctx.http.post(api_url, json={...}, timeout=120)
54
+ return ActionResult.success(
55
+ summary="Refined output ready!",
56
+ data={"text": resp.body["text"]},
57
+ )
58
+ ```
59
+
60
+ - **Manifest emission** — tools in `imperal.json` now carry `background`
61
+ and `long_running` booleans. Strict `Manifest.Tool` schema gains
62
+ matching optional fields.
63
+
64
+ ### Trade-offs vs. explicit `ctx.background_task(coro)`
65
+
66
+ - **Sugar** is best for handlers whose entire body is the long work.
67
+ - **Explicit** stays preferred when you need to return a custom
68
+ acknowledgement summary, choose `background_task()` conditionally at
69
+ runtime, or run mixed sync + background work in the same handler.
70
+
71
+ ### Migration
72
+
73
+ None required — `background` defaults to `False`. Existing
74
+ `@chat.function` handlers work unchanged.
75
+
5
76
  ## 4.2.12 — 2026-05-14
6
77
 
7
78
  **Feat: LONGRUN-V1 Session 1 — long-running operations primitives**
@@ -23,27 +94,21 @@ Three new SDK surfaces for ops that exceed the 30s `ctx.http` ceiling:
23
94
  (`LONG_RUNNING_TASK_S`). Returns task_id immediately.
24
95
 
25
96
  - **`ctx.deliver_chat_message(text, *, msg_type="response", refresh_panels=None)`**
26
- — public API for extension-initiated bot turn injection. Posts to
27
- auth-gw `/v1/internal/chat/inject`. Text truncated to 64KB with marker.
28
- `msg_type` ∈ `{response, system, tool_result}`.
97
+ — public API for extension-initiated bot turn injection. Text truncated
98
+ to 64KB with marker. `msg_type` ∈ `{response, system, tool_result}`.
29
99
 
30
100
  ### Federal invariants (new)
31
101
 
32
- - `I-LONGRUN-HTTP-CAP-180S` — per-call timeout federal cap
33
- - `I-LONGRUN-BG-CORO-RETURNS-ACTIONRESULT` — coro contract enforced
34
- kernel-side via `_explicit_background_task_completion` isinstance
35
- check; violation writes critical audit row + delivers fallback error.
36
- - `I-LONGRUN-BG-USER-SCOPED` — task bound to `(ext_id, user_id)` at
37
- creation (existing `util/task_manager.py` invariant).
38
- - `I-LONGRUN-CHAT-INJECT-USER-SCOPED` — `X-Acting-User` header must
39
- match `body.user_id` (auth-gw 403 on mismatch).
40
- - `I-LONGRUN-CHAT-INJECT-AUDIT-EVERY` — every inject writes an
41
- `action_ledger` row through the `write_audit` chokepoint.
42
-
43
- ### Spec
44
-
45
- `superpowers/specs/2026-05-13-longrun-v1-design.md`. Sessions 2 (Sharelock
46
- canary migration) and 3 (docs + observability) ship after 24h soak.
102
+ - `I-LONGRUN-HTTP-CAP-180S` — per-call timeout federal cap.
103
+ - `I-LONGRUN-BG-CORO-RETURNS-ACTIONRESULT` — the coroutine MUST return
104
+ `ActionResult`; non-ActionResult return triggers a critical audit row
105
+ and delivers a fallback error to chat.
106
+ - `I-LONGRUN-BG-USER-SCOPED` — every background task is bound to
107
+ `(ext_id, user_id)` at creation; cross-user cancel/status returns 403.
108
+ - `I-LONGRUN-CHAT-INJECT-USER-SCOPED` — chat inject scoped to
109
+ `(ext_id, user_id)`; cross-user inject returns 403.
110
+ - `I-LONGRUN-CHAT-INJECT-AUDIT-EVERY` — every chat inject writes an
111
+ audit row.
47
112
 
48
113
  ### Migration
49
114
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: imperal-sdk
3
- Version: 4.2.12
3
+ Version: 4.2.14
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.12"
42
+ __version__ = "4.2.14"
43
43
 
44
44
  __all__ = [
45
45
  # Core
@@ -58,6 +58,12 @@ class FunctionDef:
58
58
  chain_callable: bool = True # federal v4.0.0 — kernel uses typed dispatch
59
59
  effects: list[str] = field(default_factory=list) # ["create:note", "delete:folder", ...]
60
60
  id_projection: str = "" # federal v4.1.2 — params field carrying resolved target id
61
+ # LONGRUN-V1 Component D (v4.2.13+) — declarative sugar over ctx.background_task.
62
+ # When background=True, the SDK chat handler auto-wraps the function call in
63
+ # ctx.background_task(); the LLM sees an immediate ack with task_id and the
64
+ # platform delivers the handler's ActionResult as a fresh bot turn when done.
65
+ background: bool = False
66
+ long_running: bool = False
61
67
  _pydantic_model: type | None = None # auto-detected Pydantic BaseModel class
62
68
  _pydantic_param: str = "" # parameter name that receives the model instance
63
69
  _return_model: type | None = None # auto-detected return Pydantic model
@@ -115,7 +121,9 @@ class ChatExtension:
115
121
  event_schema: type | None = None,
116
122
  chain_callable: bool | None = None,
117
123
  effects: list[str] | None = None,
118
- id_projection: str | None = None):
124
+ id_projection: str | None = None,
125
+ background: bool = False,
126
+ long_running: bool = False):
119
127
  """Register a chat function (federal v4.0.0 contract).
120
128
 
121
129
  Args:
@@ -218,6 +226,8 @@ class ChatExtension:
218
226
  chain_callable=chain_callable,
219
227
  effects=list(effects or []),
220
228
  id_projection=id_projection or "",
229
+ background=background,
230
+ long_running=long_running,
221
231
  _pydantic_model=_detected_model, _pydantic_param=_detected_param,
222
232
  _return_model=_detected_return_model,
223
233
  )
@@ -236,7 +236,36 @@ async def _execute_function(
236
236
 
237
237
  while True:
238
238
  try:
239
- if _func_def._pydantic_model and _func_def._pydantic_param:
239
+ # LONGRUN-V1 Component D (v4.2.13+) declarative background-task sugar.
240
+ # When the handler is decorated with @chat.function(background=True),
241
+ # the SDK auto-wraps the call in ctx.background_task() and returns an
242
+ # immediate ack envelope to the LLM. The actual handler runs detached;
243
+ # the platform delivers its returned ActionResult as a fresh bot turn.
244
+ if getattr(_func_def, "background", False):
245
+ _bg_pydantic_model = _func_def._pydantic_model
246
+ _bg_pydantic_param = _func_def._pydantic_param
247
+ _bg_input = current_tu.input or {}
248
+ _bg_fn = _func_def.func
249
+
250
+ async def _bg_coro():
251
+ if _bg_pydantic_model and _bg_pydantic_param:
252
+ _mi = _bg_pydantic_model(**_bg_input)
253
+ return await _bg_fn(ctx, **{_bg_pydantic_param: _mi})
254
+ return await _bg_fn(ctx, **_bg_input)
255
+
256
+ _bg_task_id = await ctx.background_task(
257
+ _bg_coro(),
258
+ long_running=bool(getattr(_func_def, "long_running", False)),
259
+ name=current_tu.name,
260
+ )
261
+ result = ActionResult.success(
262
+ summary=(
263
+ f"Started '{current_tu.name}' in background — "
264
+ "the result will be sent to chat when it finishes."
265
+ ),
266
+ data={"task_id": _bg_task_id, "background": True},
267
+ )
268
+ elif _func_def._pydantic_model and _func_def._pydantic_param:
240
269
  _model_instance = _func_def._pydantic_model(**(current_tu.input or {}))
241
270
  result = await _func_def.func(ctx, **{_func_def._pydantic_param: _model_instance})
242
271
  else:
@@ -102,6 +102,8 @@ def generate_manifest(ext: Extension) -> dict:
102
102
  "params_schema": params_schema,
103
103
  "return_schema": return_schema,
104
104
  "event": fn_def.event or "",
105
+ "background": bool(getattr(fn_def, "background", False)),
106
+ "long_running": bool(getattr(fn_def, "long_running", False)),
105
107
  "scopes": [],
106
108
  "owner_chat_tool": chat_tool_name,
107
109
  })
@@ -102,6 +102,12 @@ class Tool(BaseModel):
102
102
  effects: List[str] = Field(default_factory=list)
103
103
  params_schema: Optional[Dict[str, Any]] = None
104
104
  return_schema: Optional[Dict[str, Any]] = None
105
+ # LONGRUN-V1 Component D (v4.2.13+) — declarative background-task sugar.
106
+ # When background=True, the SDK chat handler auto-wraps invocations of
107
+ # this tool in ctx.background_task(). long_running=True raises the
108
+ # federal 180s cap to 1800s.
109
+ background: Optional[bool] = None
110
+ long_running: Optional[bool] = None
105
111
  event: Optional[str] = None
106
112
  owner_chat_tool: Optional[str] = None
107
113
  synthetic: Optional[bool] = None
@@ -226,7 +226,7 @@
226
226
  },
227
227
  "SecretDecl": {
228
228
  "additionalProperties": false,
229
- "description": "One entry in `manifest['secrets']` EXT-SECRETS-V1 (v4.2.2+).\n\nMirrors :class:`imperal_sdk.secrets.spec.SecretSpec` after\n``to_manifest_dict()``. The Pydantic model exists so\n:func:`validate_manifest_dict` round-trips the emitted shape closes\nthe `I-MANIFEST-EMITTER-SCHEMA-SYMMETRIC` drift gap that lived\nsilently from v4.2.2 v4.2.7.",
229
+ "description": "One entry in `manifest['secrets']` \u2014 EXT-SECRETS-V1 (v4.2.2+).\n\nMirrors :class:`imperal_sdk.secrets.spec.SecretSpec` after\n``to_manifest_dict()``. The Pydantic model exists so\n:func:`validate_manifest_dict` round-trips the emitted shape \u2014 closes\nthe `I-MANIFEST-EMITTER-SCHEMA-SYMMETRIC` drift gap that lived\nsilently from v4.2.2 \u2192 v4.2.7.",
230
230
  "properties": {
231
231
  "name": {
232
232
  "pattern": "^[a-z][a-z0-9_]{0,62}$",
@@ -311,7 +311,7 @@
311
311
  },
312
312
  "Tool": {
313
313
  "additionalProperties": false,
314
- "description": "One entry in `manifest['tools']`.\n\nFederal v4.0.0 typed dispatch fields (action_type, chain_callable,\neffects, params_schema, return_schema, event) declared at top level so\nthe kernel chain planner can route deterministically without\nre-deriving from extension code.",
314
+ "description": "One entry in `manifest['tools']`.\n\nFederal v4.0.0 \u2014 typed dispatch fields (action_type, chain_callable,\neffects, params_schema, return_schema, event) declared at top level so\nthe kernel chain planner can route deterministically without\nre-deriving from extension code.",
315
315
  "properties": {
316
316
  "name": {
317
317
  "minLength": 1,
@@ -394,6 +394,30 @@
394
394
  "default": null,
395
395
  "title": "Return Schema"
396
396
  },
397
+ "background": {
398
+ "anyOf": [
399
+ {
400
+ "type": "boolean"
401
+ },
402
+ {
403
+ "type": "null"
404
+ }
405
+ ],
406
+ "default": null,
407
+ "title": "Background"
408
+ },
409
+ "long_running": {
410
+ "anyOf": [
411
+ {
412
+ "type": "boolean"
413
+ },
414
+ {
415
+ "type": "null"
416
+ }
417
+ ],
418
+ "default": null,
419
+ "title": "Long Running"
420
+ },
397
421
  "event": {
398
422
  "anyOf": [
399
423
  {
@@ -0,0 +1,154 @@
1
+ """Component D — @chat.function(background=True, long_running=True) decorator flag.
2
+
3
+ Sugar over ctx.background_task(coro) — the kernel auto-wraps the handler call
4
+ in ctx.background_task() under the hood; author writes one handler body, no
5
+ explicit inner coro wrapper.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import pytest
10
+ from pydantic import BaseModel
11
+
12
+ from imperal_sdk import ActionResult, Extension
13
+ from imperal_sdk.chat import ChatExtension
14
+
15
+
16
+ class _RefineParams(BaseModel):
17
+ text: str
18
+
19
+
20
+ def test_decorator_accepts_background_and_long_running_kwargs():
21
+ ext = Extension("ext-bg-test", display_name="Bg Test",
22
+ description="Background flag smoke test extension.",
23
+ actions_explicit=True)
24
+ chat = ChatExtension(ext, tool_name="ext_bg_test_chat",
25
+ description="bg test")
26
+
27
+ @chat.function(
28
+ "refine_output",
29
+ "Refine some text",
30
+ action_type="write",
31
+ event="refined",
32
+ background=True,
33
+ long_running=True,
34
+ )
35
+ async def refine_output(ctx, params: _RefineParams) -> ActionResult:
36
+ return ActionResult.success(data={"out": params.text.upper()})
37
+
38
+ fn = chat.functions["refine_output"]
39
+ assert fn.background is True
40
+ assert fn.long_running is True
41
+
42
+
43
+ def test_decorator_defaults_background_false():
44
+ ext = Extension("ext-bg-default", display_name="Bg Default",
45
+ description="Background flag default-False smoke test.",
46
+ actions_explicit=True)
47
+ chat = ChatExtension(ext, tool_name="ext_bg_default_chat",
48
+ description="default")
49
+
50
+ @chat.function("plain", "Plain handler", action_type="read")
51
+ async def plain(ctx, params: _RefineParams) -> ActionResult:
52
+ return ActionResult.success(data={"echo": params.text})
53
+
54
+ fn = chat.functions["plain"]
55
+ assert fn.background is False
56
+ assert fn.long_running is False
57
+
58
+
59
+ def test_manifest_emits_background_and_long_running():
60
+ """Tool entry in imperal.json carries the new fields."""
61
+ from imperal_sdk.manifest import generate_manifest
62
+
63
+ ext = Extension("ext-bg-manifest", display_name="Bg Manifest",
64
+ description="Background flag manifest emission test.",
65
+ actions_explicit=True)
66
+ chat = ChatExtension(ext, tool_name="ext_bg_manifest_chat",
67
+ description="manifest")
68
+
69
+ @chat.function(
70
+ "do_long_work",
71
+ "Do long work",
72
+ action_type="write",
73
+ event="work_done",
74
+ background=True,
75
+ long_running=True,
76
+ )
77
+ async def do_long_work(ctx, params: _RefineParams) -> ActionResult:
78
+ return ActionResult.success()
79
+
80
+ manifest = generate_manifest(ext)
81
+ tool_entry = next(t for t in manifest["tools"] if t["name"] == "do_long_work")
82
+ assert tool_entry["background"] is True
83
+ assert tool_entry["long_running"] is True
84
+
85
+
86
+ @pytest.mark.asyncio
87
+ async def test_handler_wraps_in_background_task_when_flag_set():
88
+ """When background=True, the SDK handler MUST call ctx.background_task
89
+ instead of running the handler synchronously. The tool result returned
90
+ to the LLM should be an ack with task_id, not the handler's return value.
91
+ """
92
+ from imperal_sdk.chat.handler import _execute_function
93
+ from imperal_sdk.context import Context
94
+ from imperal_sdk.types.identity import UserContext
95
+
96
+ # Counter to verify spawn hook was called, not the handler synchronously.
97
+ spawn_calls: list = []
98
+
99
+ async def _spawn_hook(coro, *, long_running, name):
100
+ spawn_calls.append({"long_running": long_running, "name": name})
101
+ coro.close()
102
+ return "task_bg_abc"
103
+
104
+ ext = Extension("ext-bg-runtime", display_name="Bg Runtime",
105
+ description="Background runtime wrap smoke test.",
106
+ actions_explicit=True)
107
+ chat = ChatExtension(ext, tool_name="ext_bg_runtime_chat",
108
+ description="runtime")
109
+
110
+ handler_ran = []
111
+
112
+ @chat.function(
113
+ "long_refine",
114
+ "Refine text long-running",
115
+ action_type="write",
116
+ event="refined_long",
117
+ background=True,
118
+ long_running=True,
119
+ )
120
+ async def long_refine(ctx, params: _RefineParams) -> ActionResult:
121
+ handler_ran.append(True)
122
+ return ActionResult.success(data={"result": params.text.upper()})
123
+
124
+ ctx = Context(user=UserContext(
125
+ imperal_id="imp_u_t", email="t@t.com", tenant_id="t", role="user",
126
+ ))
127
+ ctx._background_task_spawn = _spawn_hook # type: ignore[attr-defined]
128
+
129
+ # Simulate one tool call from the LLM
130
+ from types import SimpleNamespace
131
+ tu = SimpleNamespace(name="long_refine", input={"text": "hello"})
132
+
133
+ cfg = {
134
+ "max_result_tokens": 4096,
135
+ "list_truncate_items": 50,
136
+ "string_truncate_chars": 200,
137
+ }
138
+ chat._functions_called = []
139
+ result_str = await _execute_function(
140
+ chat_ext=chat, ctx=ctx, tu=tu,
141
+ action_type="write", cfg=cfg, retry_ctx=None,
142
+ )
143
+
144
+ # Spawn hook was called → handler is detached
145
+ assert len(spawn_calls) == 1
146
+ assert spawn_calls[0]["long_running"] is True
147
+ assert spawn_calls[0]["name"] == "long_refine"
148
+ # Handler body did NOT run synchronously (the coro was closed by spawn hook)
149
+ assert handler_ran == []
150
+ # Tool result returned to LLM is the background-ack envelope
151
+ import json as _j
152
+ res = _j.loads(result_str)
153
+ assert res.get("status") == "success"
154
+ assert "task_id" in (res.get("data") or {})
File without changes
File without changes
File without changes