imperal-sdk 3.2.0__tar.gz → 3.3.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 (203) hide show
  1. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/CHANGELOG.md +51 -0
  2. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/PKG-INFO +1 -1
  3. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/extension-guidelines.md +6 -1
  4. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/tools.md +4 -1
  5. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/__init__.py +1 -1
  6. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/extension.py +21 -2
  7. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/runtime/llm_provider.py +20 -1
  8. imperal_sdk-3.3.1/tests/test_chat_extension_deprecation.py +61 -0
  9. imperal_sdk-3.3.1/tests/test_openai_max_completion_tokens.py +52 -0
  10. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/.github/workflows/identity-contract.yml +0 -0
  11. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/.github/workflows/publish.yml +0 -0
  12. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/.github/workflows/test.yml +0 -0
  13. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/.gitignore +0 -0
  14. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/LICENSE +0 -0
  15. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/README.md +0 -0
  16. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/api_surface.json +0 -0
  17. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/api-reference.md +0 -0
  18. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/auth.md +0 -0
  19. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/cli.md +0 -0
  20. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/clients.md +0 -0
  21. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/concepts.md +0 -0
  22. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/context-object.md +0 -0
  23. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/context-router.md +0 -0
  24. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/extension-ui.md +0 -0
  25. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/openapi/README.md +0 -0
  26. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/openapi/auth-gateway.json +0 -0
  27. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/openapi/registry.json +0 -0
  28. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/openapi/sharelock-cases.json +0 -0
  29. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/quickstart.md +0 -0
  30. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/skeleton.md +0 -0
  31. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/testing.md +0 -0
  32. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/ui-components.md +0 -0
  33. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/examples/hello_extension/main.py +0 -0
  34. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/pyproject.toml +0 -0
  35. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/.codebase-index-cache.pkl +0 -0
  36. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ai/__init__.py +0 -0
  37. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ai/client.py +0 -0
  38. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/auth/__init__.py +0 -0
  39. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/auth/client.py +0 -0
  40. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/auth/middleware.py +0 -0
  41. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/billing/__init__.py +0 -0
  42. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/billing/client.py +0 -0
  43. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/cache/__init__.py +0 -0
  44. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/cache/client.py +0 -0
  45. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/cache/protocol.py +0 -0
  46. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/__init__.py +0 -0
  47. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/action_result.py +0 -0
  48. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/error_codes.py +0 -0
  49. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/filters.py +0 -0
  50. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/guards.py +0 -0
  51. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/handler.py +0 -0
  52. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/kernel_primitives.py +0 -0
  53. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/narration.py +0 -0
  54. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/narration_guard.py +0 -0
  55. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/prompt.py +0 -0
  56. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/refusal.py +0 -0
  57. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/cli/__init__.py +0 -0
  58. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/cli/main.py +0 -0
  59. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/config/__init__.py +0 -0
  60. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/config/client.py +0 -0
  61. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/context.py +0 -0
  62. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/db/__init__.py +0 -0
  63. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/db/client.py +0 -0
  64. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/errors.py +0 -0
  65. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/extension.py +0 -0
  66. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/extensions/__init__.py +0 -0
  67. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/extensions/client.py +0 -0
  68. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/http/__init__.py +0 -0
  69. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/http/client.py +0 -0
  70. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/manifest.py +0 -0
  71. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/manifest_schema.py +0 -0
  72. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/notify/__init__.py +0 -0
  73. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/notify/client.py +0 -0
  74. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/prompts/__init__.py +0 -0
  75. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/prompts/icnli_integrity_rules.txt +0 -0
  76. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/prompts/kernel_formatting_rule.txt +0 -0
  77. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/prompts/kernel_proactivity_rule.txt +0 -0
  78. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/protocols.py +0 -0
  79. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/rpc/__init__.py +0 -0
  80. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/rpc/codec.py +0 -0
  81. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/rpc/contract.py +0 -0
  82. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/runtime/__init__.py +0 -0
  83. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/runtime/executor.py +0 -0
  84. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/runtime/message_adapter.py +0 -0
  85. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/action_result.schema.json +0 -0
  86. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/balance_info.schema.json +0 -0
  87. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/chat_result.schema.json +0 -0
  88. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/completion_result.schema.json +0 -0
  89. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/document.schema.json +0 -0
  90. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/event.schema.json +0 -0
  91. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/file_info.schema.json +0 -0
  92. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/function_call.schema.json +0 -0
  93. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/http_response.schema.json +0 -0
  94. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/imperal.schema.json +0 -0
  95. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/limits_result.schema.json +0 -0
  96. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/subscription_info.schema.json +0 -0
  97. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/security/__init__.py +0 -0
  98. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/security/call_token.py +0 -0
  99. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/skeleton/__init__.py +0 -0
  100. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/skeleton/client.py +0 -0
  101. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/storage/__init__.py +0 -0
  102. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/storage/client.py +0 -0
  103. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/store/__init__.py +0 -0
  104. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/store/client.py +0 -0
  105. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/store/exceptions.py +0 -0
  106. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/testing/__init__.py +0 -0
  107. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/testing/mock_context.py +0 -0
  108. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/tools/__init__.py +0 -0
  109. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/tools/client.py +0 -0
  110. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/tools/generate_api_surface.py +0 -0
  111. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/tools/validate_identity_contract.py +0 -0
  112. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/__init__.py +0 -0
  113. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/action_result.py +0 -0
  114. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/chat_result.py +0 -0
  115. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/client_contracts.py +0 -0
  116. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/contracts.py +0 -0
  117. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/contributions.py +0 -0
  118. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/events.py +0 -0
  119. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/health.py +0 -0
  120. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/identity.py +0 -0
  121. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/models.py +0 -0
  122. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/pagination.py +0 -0
  123. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/store_contracts.py +0 -0
  124. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/__init__.py +0 -0
  125. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/actions.py +0 -0
  126. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/base.py +0 -0
  127. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/data.py +0 -0
  128. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/display.py +0 -0
  129. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/feedback.py +0 -0
  130. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/graph.py +0 -0
  131. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/input_components.py +0 -0
  132. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/interactive.py +0 -0
  133. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/layout.py +0 -0
  134. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/theme.py +0 -0
  135. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/validator.py +0 -0
  136. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/validator_v1_6_0.py +0 -0
  137. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/conftest.py +0 -0
  138. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/contracts/__init__.py +0 -0
  139. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/contracts/test_store_contracts.py +0 -0
  140. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/rpc/__init__.py +0 -0
  141. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/rpc/test_codec.py +0 -0
  142. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/rpc/test_contract.py +0 -0
  143. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/runtime/__init__.py +0 -0
  144. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/runtime/test_llm_provider_config_store.py +0 -0
  145. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/runtime/test_llm_provider_ctx_injection.py +0 -0
  146. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/store/__init__.py +0 -0
  147. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/store/test_list_users_client.py +0 -0
  148. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/store/test_query_all_client.py +0 -0
  149. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_action_result_typed.py +0 -0
  150. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_as_user.py +0 -0
  151. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_auth.py +0 -0
  152. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_billing.py +0 -0
  153. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_cache_client.py +0 -0
  154. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_cache_model.py +0 -0
  155. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_call_token.py +0 -0
  156. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_chat_filters.py +0 -0
  157. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_chat_guards.py +0 -0
  158. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_chat_guards_bleed.py +0 -0
  159. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_chat_prompt.py +0 -0
  160. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_chat_result.py +0 -0
  161. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_cli.py +0 -0
  162. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_client_contracts.py +0 -0
  163. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_config_client.py +0 -0
  164. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_context.py +0 -0
  165. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_context_guards.py +0 -0
  166. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_contracts.py +0 -0
  167. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_contracts_live.py +0 -0
  168. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_contributions.py +0 -0
  169. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_document_contract.py +0 -0
  170. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_error_codes.py +0 -0
  171. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_errors.py +0 -0
  172. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_events_health.py +0 -0
  173. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_extension.py +0 -0
  174. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_extension_v2.py +0 -0
  175. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_handler_p2.py +0 -0
  176. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_identity_contract.py +0 -0
  177. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_kernel_primitives.py +0 -0
  178. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_manifest.py +0 -0
  179. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_manifest_schema.py +0 -0
  180. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_mock_context.py +0 -0
  181. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_models.py +0 -0
  182. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_narration_emission.py +0 -0
  183. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_narration_guard.py +0 -0
  184. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_pagination.py +0 -0
  185. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_panels.py +0 -0
  186. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_skeleton_decorator.py +0 -0
  187. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_spec_validation.py +0 -0
  188. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_tools_client.py +0 -0
  189. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_ui.py +0 -0
  190. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_ui_fileupload_enhanced.py +0 -0
  191. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_ui_html.py +0 -0
  192. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_ui_image_enhanced.py +0 -0
  193. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_ui_open.py +0 -0
  194. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_ui_theme.py +0 -0
  195. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_user.py +0 -0
  196. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_v7_emit_refusal.py +0 -0
  197. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_validator.py +0 -0
  198. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_validator_drift.py +0 -0
  199. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_validator_pep563.py +0 -0
  200. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_validator_v1_6_0_rules.py +0 -0
  201. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_write_arg_bleed.py +0 -0
  202. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/tools/__init__.py +0 -0
  203. {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/tools/test_generate_api_surface.py +0 -0
@@ -2,6 +2,57 @@
2
2
 
3
3
  All notable changes to `imperal-sdk` are documented here.
4
4
 
5
+ ## 3.3.1 — 2026-04-29 — LLM-FU-1: gpt-5 / o-series max_completion_tokens
6
+
7
+ ### Fixed
8
+
9
+ - `LLMProvider._call_openai` now sends `max_completion_tokens` instead of
10
+ the legacy `max_tokens` kwarg when the resolved config matches OpenAI
11
+ reasoning models — `gpt-5`, `gpt-5-mini`, `gpt-5-nano`, `o1*`, `o3*`,
12
+ `o4*`. OpenAI rejects `max_tokens` for these families with
13
+ `'max_tokens' is not supported with this model. Use 'max_completion_tokens' instead.`,
14
+ which surfaced after the 2026-04-29 admin LLM dropdown expansion added
15
+ these models. Anthropic, Gemini (OpenAI-compat), and Ollama/vLLM
16
+ (`openai_compatible`) keep `max_tokens` — sending the new kwarg to
17
+ those providers is unsafe.
18
+ - Helper `_openai_uses_max_completion_tokens(provider, model)` gates the
19
+ rename; matches by model-name prefix (`gpt-5`, `o1`, `o3`, `o4`)
20
+ case-insensitively, scoped to `provider == "openai"` only.
21
+
22
+ ### Tests
23
+
24
+ - `tests/test_openai_max_completion_tokens.py` — 24 parametrized cases
25
+ covering reasoning models, legacy OpenAI, cross-provider safety, and
26
+ edge cases (empty model, empty provider).
27
+
28
+ ## 3.3.0 — 2026-04-28 — UI extensions + deprecation (Sprint 2)
29
+
30
+ ### Deprecated
31
+
32
+ - `ChatExtension(model=...)` constructor parameter is now deprecated.
33
+ Default changes from `"claude-haiku-4-5-20251001"` → `None`. When
34
+ explicitly passed, emits a class-level WARN-once log:
35
+ > `ChatExtension(tool_name=...): the model= parameter is deprecated
36
+ > since SDK 3.3.0. LLM model resolution moved to kernel ctx-injection
37
+ > (see ctx._llm_configs). Will be removed in SDK 4.0.0.`
38
+ - Backward compat preserved until SDK 4.0.0 — out-of-tree extensions
39
+ passing `model=` continue to work; in-tree extensions cleaned of the
40
+ parameter as part of this sprint.
41
+
42
+ ### Federal
43
+
44
+ - `_model_deprecation_warned` flag is class-level (not instance-level)
45
+ so 11 in-tree extensions don't each warn at boot during transition
46
+ state. After they migrate, the warn fires only for external
47
+ out-of-tree extensions until they update.
48
+ - Companion: Admin > LLM Config UI gains `chain_narrative_model` +
49
+ `judge_model` Select rows (admin extension change shipped in
50
+ `/opt/extensions` monorepo + 7 inner-git extensions per Developer
51
+ Portal convention).
52
+ - Documentation: SDK docs `extension-guidelines.md` + `tools.md`
53
+ ChatExtension examples updated to omit `model=`. External
54
+ developers reading docs do not propagate the deprecated pattern.
55
+
5
56
  ## 3.2.0 — 2026-04-28 — Architectural cleanup (Sprint 1.2)
6
57
 
7
58
  ### Changed (BREAKING-internal — public API preserved with shim)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: imperal-sdk
3
- Version: 3.2.0
3
+ Version: 3.3.1
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
@@ -50,8 +50,13 @@ chat = ChatExtension(
50
50
  tool_name="tool_myapp_chat",
51
51
  description="Clear description of ALL capabilities for embedding search",
52
52
  system_prompt="You are the My App assistant. You handle X, Y, Z.",
53
- model="claude-haiku-4-5-20251001",
54
53
  )
54
+ # NOTE (SDK 3.3.0+): the `model=` constructor parameter is DEPRECATED
55
+ # and will be removed in SDK 4.0.0. LLM model resolution moved to
56
+ # kernel ctx-injection (Sprint 1.2): ctx._llm_configs[purpose] is
57
+ # pre-resolved by kernel context_factory based on Admin > LLM Config.
58
+ # Out-of-tree extensions still passing `model=` continue to work but
59
+ # emit a class-level WARN-once at boot.
55
60
 
56
61
  class DoXParams(BaseModel):
57
62
  input: str
@@ -153,8 +153,11 @@ chat_ext = ChatExtension(
153
153
  tool_name="tool_notes_chat",
154
154
  description="Notes management — create, list, update, delete notes",
155
155
  system_prompt="You manage the user's notes. Call functions for all note operations.",
156
- model="claude-haiku-4-5-20251001",
157
156
  )
157
+ # SDK 3.3.0+: do not pass `model=` — it's deprecated.
158
+ # LLM resolution happens via kernel ctx-injection
159
+ # (ctx._llm_configs[purpose]). Admin > LLM Config controls
160
+ # the model centrally for all extensions.
158
161
 
159
162
  @chat_ext.function("list_notes", action_type="read",
160
163
  description="List all notes", params={"folder": {"type": "string", "description": "Filter by folder", "default": None}})
@@ -33,7 +33,7 @@ from imperal_sdk.validator_v1_6_0 import (
33
33
  validate_manifest_v1_6_0,
34
34
  )
35
35
 
36
- __version__ = "3.2.0"
36
+ __version__ = "3.3.1"
37
37
 
38
38
  __all__ = [
39
39
  # Core
@@ -39,12 +39,31 @@ class FunctionDef:
39
39
 
40
40
  class ChatExtension:
41
41
  def __init__(self, ext, tool_name: str, description: str, system_prompt: str = "",
42
- model: str = "claude-haiku-4-5-20251001", max_rounds: int = 10):
42
+ model: "str | None" = None, max_rounds: int = 10):
43
43
  self.ext = ext
44
44
  self.tool_name = tool_name
45
45
  self.description = description
46
46
  self.system_prompt = system_prompt
47
- self.model = model
47
+ # Sprint 2 (2026-04-28): the `model=` parameter is deprecated.
48
+ # LLM resolution moved to kernel ctx-injection (see ctx._llm_configs)
49
+ # in Sprint 1.2. Removing the constructor argument entirely is
50
+ # scheduled for SDK 4.0.0 — until then we keep it for backward
51
+ # compat but emit a class-level WARN-once when it's explicitly
52
+ # passed. The flag is on the CLASS (not instance) so 11
53
+ # extensions don't each warn at boot.
54
+ if model is not None:
55
+ if not getattr(ChatExtension, "_model_deprecation_warned", False):
56
+ log.warning(
57
+ f"ChatExtension(tool_name={tool_name!r}, model=...): "
58
+ "the `model=` parameter is deprecated since SDK 3.3.0. "
59
+ "LLM model resolution moved to kernel ctx-injection (see "
60
+ "ctx._llm_configs). Will be removed in SDK 4.0.0. "
61
+ "Remove `model=` from extension app.py."
62
+ )
63
+ ChatExtension._model_deprecation_warned = True
64
+ self.model = model
65
+ else:
66
+ self.model = "" # historical default no longer meaningful
48
67
  self.max_rounds = max_rounds
49
68
  self._functions: dict[str, FunctionDef] = {}
50
69
  _self = self
@@ -58,6 +58,20 @@ _ENV_FB_API_KEY = os.getenv("LLM_FALLBACK_API_KEY", "")
58
58
  _ENV_FB_MODEL = os.getenv("LLM_FALLBACK_MODEL", "")
59
59
  _ENV_FB_BASE_URL = os.getenv("LLM_FALLBACK_BASE_URL", "")
60
60
 
61
+
62
+ # OpenAI gpt-5 family + o-series reasoning models (o1/o3/o4) reject the
63
+ # legacy `max_tokens` kwarg with "'max_tokens' is not supported with this
64
+ # model. Use 'max_completion_tokens' instead." Other providers (Anthropic,
65
+ # Gemini via OpenAI-compat, Ollama/vLLM via openai_compatible) keep
66
+ # `max_tokens` — sending `max_completion_tokens` to them is unsafe.
67
+ _OPENAI_MCT_MODEL_PREFIXES = ("gpt-5", "o1", "o3", "o4")
68
+
69
+
70
+ def _openai_uses_max_completion_tokens(provider: str, model: str) -> bool:
71
+ if provider != "openai" or not model:
72
+ return False
73
+ return model.lower().startswith(_OPENAI_MCT_MODEL_PREFIXES)
74
+
61
75
  _GATEWAY_URL = os.getenv("IMPERAL_GATEWAY_URL", "")
62
76
  _SERVICE_TOKEN = os.getenv("IMPERAL_SERVICE_TOKEN", "")
63
77
 
@@ -446,9 +460,14 @@ class LLMProvider:
446
460
 
447
461
  client = self._get_client(cfg)
448
462
  oai_messages = MessageAdapter.to_openai_messages(messages, system)
463
+ _token_kwarg = (
464
+ "max_completion_tokens"
465
+ if _openai_uses_max_completion_tokens(cfg.provider, cfg.model)
466
+ else "max_tokens"
467
+ )
449
468
  kwargs: dict[str, Any] = {
450
469
  "model": cfg.model,
451
- "max_tokens": max_tokens,
470
+ _token_kwarg: max_tokens,
452
471
  "messages": oai_messages,
453
472
  "temperature": temperature,
454
473
  }
@@ -0,0 +1,61 @@
1
+ """Tests for ChatExtension(model=...) deprecation (Sprint 2).
2
+
3
+ After Sprint 2:
4
+ - model default → None (was "claude-haiku-4-5-20251001")
5
+ - self.model defaults to "" when no model= passed
6
+ - WARN-once class-level fires when model explicitly passed
7
+ """
8
+ import logging
9
+ import pytest
10
+
11
+ from imperal_sdk import Extension
12
+ from imperal_sdk.chat import ChatExtension
13
+
14
+
15
+ @pytest.fixture(autouse=True)
16
+ def reset_warned_flag():
17
+ """Reset class-level warn-once flag between tests for isolation."""
18
+ if hasattr(ChatExtension, "_model_deprecation_warned"):
19
+ delattr(ChatExtension, "_model_deprecation_warned")
20
+ yield
21
+ if hasattr(ChatExtension, "_model_deprecation_warned"):
22
+ delattr(ChatExtension, "_model_deprecation_warned")
23
+
24
+
25
+ def test_chat_extension_no_model_default_is_empty():
26
+ """ChatExtension(...) without model= → chat_ext.model is empty string."""
27
+ ext = Extension("test-ext", version="1.0.0")
28
+ chat_ext = ChatExtension(ext=ext, tool_name="t1", description="d1")
29
+ assert chat_ext.model == "", (
30
+ f"expected empty model when omitted; got {chat_ext.model!r}"
31
+ )
32
+
33
+
34
+ def test_chat_extension_passing_model_warns_once(caplog):
35
+ """Two ChatExtension(model=) calls → exactly 1 DEPRECATION warn."""
36
+ ext1 = Extension("test1", version="1.0.0")
37
+ ext2 = Extension("test2", version="1.0.0")
38
+ with caplog.at_level(logging.WARNING, logger="imperal_sdk.chat.extension"):
39
+ ChatExtension(ext=ext1, tool_name="t1", description="d1", model="x")
40
+ ChatExtension(ext=ext2, tool_name="t2", description="d2", model="y")
41
+
42
+ deprecation_warns = [
43
+ r for r in caplog.records
44
+ if r.levelname == "WARNING" and "deprecated" in r.message.lower()
45
+ ]
46
+ assert len(deprecation_warns) == 1, (
47
+ f"expected 1 DEPRECATION warn (class-level once); got {len(deprecation_warns)}"
48
+ )
49
+
50
+
51
+ def test_chat_extension_no_warn_when_model_omitted(caplog):
52
+ """ChatExtension(...) without model= MUST NOT trigger DEPRECATION."""
53
+ ext = Extension("test-ext", version="1.0.0")
54
+ with caplog.at_level(logging.WARNING, logger="imperal_sdk.chat.extension"):
55
+ ChatExtension(ext=ext, tool_name="t1", description="d1")
56
+
57
+ deprecation_warns = [
58
+ r for r in caplog.records
59
+ if r.levelname == "WARNING" and "deprecated" in r.message.lower()
60
+ ]
61
+ assert len(deprecation_warns) == 0
@@ -0,0 +1,52 @@
1
+ """Regression for LLM-FU-1 (2026-04-29).
2
+
3
+ OpenAI gpt-5 family + o-series reasoning models (o1/o3/o4) reject the legacy
4
+ `max_tokens` kwarg. The SDK runtime LLM provider must rename it to
5
+ `max_completion_tokens` for that family only — other providers and other
6
+ OpenAI models keep `max_tokens`.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import pytest
11
+
12
+ from imperal_sdk.runtime.llm_provider import _openai_uses_max_completion_tokens
13
+
14
+
15
+ @pytest.mark.parametrize(
16
+ "provider,model,expected",
17
+ [
18
+ # gpt-5 family — must use max_completion_tokens
19
+ ("openai", "gpt-5", True),
20
+ ("openai", "gpt-5-mini", True),
21
+ ("openai", "gpt-5-nano", True),
22
+ ("openai", "GPT-5-Mini", True), # case-insensitive
23
+ # o-series reasoning models
24
+ ("openai", "o1", True),
25
+ ("openai", "o1-mini", True),
26
+ ("openai", "o1-preview", True),
27
+ ("openai", "o3", True),
28
+ ("openai", "o3-mini", True),
29
+ ("openai", "o4-mini", True),
30
+ # Legacy OpenAI models — must keep max_tokens
31
+ ("openai", "gpt-4o", False),
32
+ ("openai", "gpt-4o-mini", False),
33
+ ("openai", "gpt-4-turbo", False),
34
+ ("openai", "gpt-3.5-turbo", False),
35
+ ("openai", "gpt-4.1", False),
36
+ ("openai", "gpt-4.1-mini", False),
37
+ # Other providers — never use max_completion_tokens regardless of model name
38
+ ("anthropic", "claude-sonnet-4-6-20251001", False),
39
+ ("anthropic", "gpt-5", False), # nonsense combo, but provider gates the rename
40
+ ("google", "gemini-2.5-pro", False),
41
+ ("google", "gpt-5", False),
42
+ ("openai_compatible", "gpt-5", False), # Ollama serving misnamed model
43
+ ("openai_compatible", "qwen3:27b", False),
44
+ # Edge cases
45
+ ("openai", "", False),
46
+ ("", "gpt-5", False),
47
+ ],
48
+ )
49
+ def test_openai_uses_max_completion_tokens(
50
+ provider: str, model: str, expected: bool
51
+ ) -> None:
52
+ assert _openai_uses_max_completion_tokens(provider, model) is expected
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes