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.
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/CHANGELOG.md +51 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/PKG-INFO +1 -1
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/extension-guidelines.md +6 -1
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/tools.md +4 -1
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/__init__.py +1 -1
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/extension.py +21 -2
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/runtime/llm_provider.py +20 -1
- imperal_sdk-3.3.1/tests/test_chat_extension_deprecation.py +61 -0
- imperal_sdk-3.3.1/tests/test_openai_max_completion_tokens.py +52 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/.github/workflows/identity-contract.yml +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/.github/workflows/publish.yml +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/.github/workflows/test.yml +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/.gitignore +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/LICENSE +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/README.md +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/api_surface.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/api-reference.md +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/auth.md +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/cli.md +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/clients.md +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/concepts.md +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/context-object.md +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/context-router.md +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/extension-ui.md +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/openapi/README.md +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/openapi/auth-gateway.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/openapi/registry.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/openapi/sharelock-cases.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/quickstart.md +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/skeleton.md +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/testing.md +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/docs/ui-components.md +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/examples/hello_extension/main.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/pyproject.toml +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/.codebase-index-cache.pkl +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ai/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ai/client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/auth/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/auth/client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/auth/middleware.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/billing/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/billing/client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/cache/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/cache/client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/cache/protocol.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/action_result.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/error_codes.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/filters.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/guards.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/handler.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/kernel_primitives.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/narration.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/narration_guard.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/prompt.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/chat/refusal.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/cli/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/cli/main.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/config/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/config/client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/context.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/db/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/db/client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/errors.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/extension.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/extensions/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/extensions/client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/http/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/http/client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/manifest.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/manifest_schema.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/notify/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/notify/client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/prompts/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/prompts/icnli_integrity_rules.txt +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/prompts/kernel_formatting_rule.txt +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/prompts/kernel_proactivity_rule.txt +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/protocols.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/rpc/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/rpc/codec.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/rpc/contract.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/runtime/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/runtime/executor.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/runtime/message_adapter.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/action_result.schema.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/balance_info.schema.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/chat_result.schema.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/completion_result.schema.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/document.schema.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/event.schema.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/file_info.schema.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/function_call.schema.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/http_response.schema.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/imperal.schema.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/limits_result.schema.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/subscription_info.schema.json +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/security/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/security/call_token.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/skeleton/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/skeleton/client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/storage/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/storage/client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/store/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/store/client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/store/exceptions.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/testing/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/testing/mock_context.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/tools/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/tools/client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/tools/generate_api_surface.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/tools/validate_identity_contract.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/action_result.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/chat_result.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/client_contracts.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/contracts.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/contributions.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/events.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/health.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/identity.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/models.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/pagination.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/types/store_contracts.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/actions.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/base.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/data.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/display.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/feedback.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/graph.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/input_components.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/interactive.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/layout.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/ui/theme.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/validator.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/validator_v1_6_0.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/conftest.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/contracts/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/contracts/test_store_contracts.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/rpc/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/rpc/test_codec.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/rpc/test_contract.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/runtime/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/runtime/test_llm_provider_config_store.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/runtime/test_llm_provider_ctx_injection.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/store/__init__.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/store/test_list_users_client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/store/test_query_all_client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_action_result_typed.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_as_user.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_auth.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_billing.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_cache_client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_cache_model.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_call_token.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_chat_filters.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_chat_guards.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_chat_guards_bleed.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_chat_prompt.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_chat_result.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_cli.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_client_contracts.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_config_client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_context.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_context_guards.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_contracts.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_contracts_live.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_contributions.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_document_contract.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_error_codes.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_errors.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_events_health.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_extension.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_extension_v2.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_handler_p2.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_identity_contract.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_kernel_primitives.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_manifest.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_manifest_schema.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_mock_context.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_models.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_narration_emission.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_narration_guard.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_pagination.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_panels.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_skeleton_decorator.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_spec_validation.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_tools_client.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_ui.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_ui_fileupload_enhanced.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_ui_html.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_ui_image_enhanced.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_ui_open.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_ui_theme.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_user.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_v7_emit_refusal.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_validator.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_validator_drift.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_validator_pep563.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_validator_v1_6_0_rules.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/test_write_arg_bleed.py +0 -0
- {imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/tests/tools/__init__.py +0 -0
- {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)
|
|
@@ -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}})
|
|
@@ -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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/completion_result.schema.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{imperal_sdk-3.2.0 → imperal_sdk-3.3.1}/src/imperal_sdk/schemas/subscription_info.schema.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|