imperal-sdk 4.2.2__tar.gz → 4.2.4__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-4.2.2 → imperal_sdk-4.2.4}/CHANGELOG.md +57 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/PKG-INFO +1 -1
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/__init__.py +1 -1
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/extension.py +35 -0
- imperal_sdk-4.2.4/src/imperal_sdk/secrets/panel_handler.py +133 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/.github/workflows/identity-contract.yml +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/.github/workflows/publish.yml +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/.github/workflows/test.yml +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/.gitignore +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/LICENSE +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/README.md +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/api_surface.json +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/pyproject.toml +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/.codebase-index-cache.pkl +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/ai/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/ai/client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/auth/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/auth/client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/auth/middleware.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/billing/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/billing/client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/cache/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/cache/client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/cache/protocol.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/chat/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/chat/action_result.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/chat/error_codes.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/chat/extension.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/chat/filters.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/chat/guards.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/chat/handler.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/chat/kernel_primitives.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/chat/narration.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/chat/narration_guard.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/chat/prompt.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/chat/refusal.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/chat/retry.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/cli/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/cli/main.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/config/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/config/client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/context.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/db/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/db/client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/errors.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/extensions/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/extensions/client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/http/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/http/client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/manifest.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/manifest_schema.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/notify/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/notify/client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/prompts/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/prompts/icnli_integrity_rules.txt +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/prompts/kernel_formatting_rule.txt +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/prompts/kernel_proactivity_rule.txt +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/protocols.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/rpc/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/rpc/codec.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/rpc/contract.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/runtime/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/runtime/executor.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/runtime/llm_provider.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/runtime/message_adapter.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/schemas/action_result.schema.json +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/schemas/balance_info.schema.json +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/schemas/chat_result.schema.json +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/schemas/completion_result.schema.json +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/schemas/document.schema.json +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/schemas/event.schema.json +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/schemas/file_info.schema.json +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/schemas/function_call.schema.json +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/schemas/http_response.schema.json +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/schemas/imperal.schema.json +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/schemas/limits_result.schema.json +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/schemas/subscription_info.schema.json +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/secrets/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/secrets/client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/secrets/exceptions.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/secrets/spec.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/security/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/security/call_token.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/skeleton/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/skeleton/client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/storage/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/storage/client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/store/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/store/client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/store/exceptions.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/testing/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/testing/mock_context.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/testing/mock_secrets.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/tools/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/tools/client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/tools/generate_api_surface.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/tools/validate_identity_contract.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/types/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/types/action_result.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/types/chat_result.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/types/client_contracts.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/types/contracts.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/types/contributions.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/types/events.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/types/health.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/types/identity.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/types/models.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/types/pagination.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/types/store_contracts.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/ui/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/ui/actions.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/ui/base.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/ui/data.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/ui/display.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/ui/feedback.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/ui/graph.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/ui/input_components.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/ui/interactive.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/ui/layout.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/ui/theme.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/validator.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/src/imperal_sdk/validator_v1_6_0.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/conftest.py +0 -0
- {imperal_sdk-4.2.2/tests/tools → imperal_sdk-4.2.4/tests/contracts}/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/contracts/test_store_contracts.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/fixtures/openapi/auth-gateway.json +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/fixtures/openapi/registry.json +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/fixtures/openapi/sharelock-cases.json +0 -0
- {imperal_sdk-4.2.2/tests/store → imperal_sdk-4.2.4/tests/rpc}/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/rpc/test_codec.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/rpc/test_contract.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/runtime/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/runtime/test_llm_provider_config_store.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/runtime/test_llm_provider_ctx_injection.py +0 -0
- {imperal_sdk-4.2.2/tests/rpc → imperal_sdk-4.2.4/tests/store}/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/store/test_list_users_client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/store/test_query_all_client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_action_result_typed.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_as_user.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_auth.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_billing.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_cache_client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_cache_model.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_call_token.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_chat_extension_deprecation.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_chat_filters.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_chat_guards.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_chat_guards_bleed.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_chat_prompt.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_chat_pydantic_retry.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_chat_result.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_cli.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_client_contracts.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_config_client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_context.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_context_guards.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_contracts.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_contracts_live.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_contributions.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_document_contract.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_emits_decorator.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_error_codes.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_errors.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_event_schema_v2.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_events_health.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_extension.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_extension_v2.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_extensions_emit.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_handler_p2.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_id_shape_guard.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_identity_contract.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_imperal_schema_v2.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_kernel_primitives.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_manifest.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_manifest_roundtrip_gate.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_manifest_schema.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_manifest_v2_events.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_manifest_v2_other_sections.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_manifest_v2_webhooks.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_manifest_validator_v2.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_mock_context.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_models.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_narration_emission.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_narration_guard.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_openai_max_completion_tokens.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_pagination.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_panel_rendering_contract.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_panels.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_skeleton_decorator.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_spec_validation.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_tools_client.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_ui.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_ui_fileupload_enhanced.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_ui_html.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_ui_image_enhanced.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_ui_open.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_ui_theme.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_user.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_v7_emit_refusal.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_validator.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_validator_drift.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_validator_pep563.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_validator_v1_6_0_rules.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/test_write_arg_bleed.py +0 -0
- {imperal_sdk-4.2.2/tests/contracts → imperal_sdk-4.2.4/tests/tools}/__init__.py +0 -0
- {imperal_sdk-4.2.2 → imperal_sdk-4.2.4}/tests/tools/test_generate_api_surface.py +0 -0
|
@@ -2,6 +2,63 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `imperal-sdk` are documented here.
|
|
4
4
|
|
|
5
|
+
## 4.2.4 — 2026-05-13
|
|
6
|
+
|
|
7
|
+
**EXT-SECRETS-V1 — unconditional synthetic Secrets panel**
|
|
8
|
+
|
|
9
|
+
In v4.2.3 the synthetic Secrets panel was registered conditionally on the
|
|
10
|
+
first `@ext.secret(...)` call, which meant extensions that did not declare
|
|
11
|
+
secrets had no menu entry — leaving end-users without a discoverable place
|
|
12
|
+
to manage credentials when developers later add declarations.
|
|
13
|
+
|
|
14
|
+
This release flips the registration to **unconditional**: every Extension
|
|
15
|
+
instance auto-registers the synthetic `secrets` panel in `__init__` (slot
|
|
16
|
+
`right`, title `Secrets`, icon `KeyRound`). When the manifest has zero
|
|
17
|
+
declared secrets, the panel renders an empty state with developer guidance
|
|
18
|
+
(`@ext.secret(...)` code example + link to docs). When declarations exist,
|
|
19
|
+
it renders one card per secret with `is_set` status + Manage button.
|
|
20
|
+
|
|
21
|
+
### Migration notes
|
|
22
|
+
|
|
23
|
+
- **No code changes required**. Bump your ext's SDK pin to `>= 4.2.4` and
|
|
24
|
+
redeploy via Dev Portal — the Secrets tab appears automatically.
|
|
25
|
+
- Extensions that genuinely never need credentials still get the tab; this
|
|
26
|
+
is intentional for UX consistency. Federal V32 contract still requires
|
|
27
|
+
`@ext.secret` for any real credential access at runtime.
|
|
28
|
+
|
|
29
|
+
## 4.2.3 — 2026-05-13
|
|
30
|
+
|
|
31
|
+
**EXT-SECRETS-V1 UX polish — synthetic `secrets` panel auto-injected**
|
|
32
|
+
|
|
33
|
+
When an extension declares one or more `@ext.secret(...)` entries, the SDK
|
|
34
|
+
now auto-registers a synthetic `secrets` panel (slot=`right`, title=`Secrets`,
|
|
35
|
+
icon=`KeyRound`) so the user-facing Secrets manager appears alongside the
|
|
36
|
+
extension's own tabs without the author writing any panel code.
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
|
|
40
|
+
- **Auto-injected `secrets` panel**: `Extension.secret(...)` on first call
|
|
41
|
+
registers a built-in handler from `imperal_sdk.secrets.panel_handler`. The
|
|
42
|
+
handler reads declared secrets + live is_set state from `ctx.secrets.list()`
|
|
43
|
+
and renders `ui.Card` rows with status badges + a `Manage` button that
|
|
44
|
+
routes to the dedicated `/ext/{ext_id}/secrets` page.
|
|
45
|
+
- The synthetic panel uses **slot=`right`** defensively — most extensions use
|
|
46
|
+
`left` (sidebar nav) and `center` (main content); `right` is rarely-used so
|
|
47
|
+
the panel-sync logic in `imperal-ext-developer` won't overwrite it. If your
|
|
48
|
+
extension already declares a `right`-slot panel, your panel wins; users
|
|
49
|
+
still reach the Secrets UI via the chat-top ribbon and the direct
|
|
50
|
+
`/ext/{ext_id}/secrets` route.
|
|
51
|
+
- Panel idempotent — multiple `@ext.secret(...)` calls register the panel
|
|
52
|
+
only once.
|
|
53
|
+
|
|
54
|
+
### Migration notes
|
|
55
|
+
|
|
56
|
+
- **No code changes required** to receive the synthetic panel. Bump your
|
|
57
|
+
ext's SDK pin to `>= 4.2.3` and redeploy via Dev Portal.
|
|
58
|
+
- Once your extension is on v4.2.3+, the chat-top ribbon (added in Panel for
|
|
59
|
+
v4.2.2 discoverability) becomes redundant for that ext — synthetic panel
|
|
60
|
+
appears in the `right` slot as a proper tab.
|
|
61
|
+
|
|
5
62
|
## 4.2.2 — 2026-05-13
|
|
6
63
|
|
|
7
64
|
### Added — EXT-SECRETS-V1 (closes ARCH-D1 in compliance-posture.md)
|
|
@@ -142,6 +142,36 @@ class Extension:
|
|
|
142
142
|
# EXT-SECRETS-V1 (v4.2.2) — declared secrets emitted into manifest.secrets[]
|
|
143
143
|
self._secrets: dict[str, "SecretSpec"] = {}
|
|
144
144
|
|
|
145
|
+
# EXT-SECRETS-V1 (v4.2.4) — auto-register synthetic 'secrets' panel
|
|
146
|
+
# unconditionally for every Extension. Empty state (no @ext.secret
|
|
147
|
+
# declared) renders developer guidance with code example. Federal
|
|
148
|
+
# contract enforced platform-side regardless of UI presence.
|
|
149
|
+
self._auto_register_secrets_panel()
|
|
150
|
+
|
|
151
|
+
def _auto_register_secrets_panel(self) -> None:
|
|
152
|
+
"""Register the platform-provided 'secrets' panel.
|
|
153
|
+
|
|
154
|
+
Idempotent — only registers once per Extension instance. Slot
|
|
155
|
+
defaults to 'right' (least-used by typical extensions, lowest
|
|
156
|
+
collision risk with deploy-sync logic that keeps one panel per slot).
|
|
157
|
+
"""
|
|
158
|
+
if "secrets" in self._panels:
|
|
159
|
+
return
|
|
160
|
+
try:
|
|
161
|
+
from imperal_sdk.secrets.panel_handler import (
|
|
162
|
+
builtin_secrets_panel_handler,
|
|
163
|
+
)
|
|
164
|
+
except Exception:
|
|
165
|
+
# If secrets package import fails, don't break Extension init.
|
|
166
|
+
return
|
|
167
|
+
self.panel(
|
|
168
|
+
"secrets",
|
|
169
|
+
slot="right",
|
|
170
|
+
title="Secrets",
|
|
171
|
+
icon="KeyRound",
|
|
172
|
+
refresh="manual",
|
|
173
|
+
)(builtin_secrets_panel_handler)
|
|
174
|
+
|
|
145
175
|
def secret(
|
|
146
176
|
self,
|
|
147
177
|
name: str,
|
|
@@ -195,6 +225,11 @@ class Extension:
|
|
|
195
225
|
)
|
|
196
226
|
self._secrets[name] = spec
|
|
197
227
|
|
|
228
|
+
# EXT-SECRETS-V1 (v4.2.4): synthetic Secrets panel is now registered
|
|
229
|
+
# unconditionally in Extension.__init__ via _auto_register_secrets_panel.
|
|
230
|
+
# This call site is a no-op safety net for older bytecode paths.
|
|
231
|
+
self._auto_register_secrets_panel()
|
|
232
|
+
|
|
198
233
|
def _decorator(target):
|
|
199
234
|
return target # syntactic anchor only — decorator is a no-op wrapper
|
|
200
235
|
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"""Built-in handler for the synthetic ``secrets`` panel.
|
|
2
|
+
|
|
3
|
+
When an Extension declares one or more ``@ext.secret(...)`` entries, the SDK
|
|
4
|
+
auto-registers a panel with ``panel_id='secrets'`` so the user-facing
|
|
5
|
+
Secrets manager appears among the extension's other tabs (Overview /
|
|
6
|
+
Analytics / Transactions / ...). The extension author doesn't write any
|
|
7
|
+
panel code — the SDK provides this canonical handler.
|
|
8
|
+
|
|
9
|
+
Federal contract: the handler renders a summary of declared secrets +
|
|
10
|
+
links to the full /ext/{ext_id}/secrets page where Panel UI handles
|
|
11
|
+
PUT/DELETE through type=password input + cleared-on-submit state. We
|
|
12
|
+
do NOT inline the input form here because the canonical UI lives in
|
|
13
|
+
Panel React (SecretManagerCard) — duplicating it in declarative ui.*
|
|
14
|
+
primitives would split the federal contract (I-SECRETS-NEVER-LOGGED,
|
|
15
|
+
no-echo, no-clipboard) across two implementations.
|
|
16
|
+
"""
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
async def builtin_secrets_panel_handler(ctx: Any, **_params: Any) -> dict:
|
|
23
|
+
"""Render the synthetic secrets panel.
|
|
24
|
+
|
|
25
|
+
Returns a UINode dict (post-``.to_dict()``) that the kernel relays to
|
|
26
|
+
Imperal Panel. The panel shows one card per declared secret with
|
|
27
|
+
is_set status badge and a primary action that navigates to
|
|
28
|
+
/ext/{ext_id}/secrets — the full SecretManagerCard route.
|
|
29
|
+
"""
|
|
30
|
+
# Import inside the handler to keep SDK init light and avoid
|
|
31
|
+
# circular imports if ui.* itself imports anything from secrets.
|
|
32
|
+
from imperal_sdk import ui
|
|
33
|
+
|
|
34
|
+
ext_id = getattr(ctx, "ext_id", "") or getattr(ctx, "extension_id", "") or ""
|
|
35
|
+
|
|
36
|
+
# Pull declared secrets from ctx if the kernel populated them; fall
|
|
37
|
+
# back to an empty list so the panel still renders cleanly.
|
|
38
|
+
declared = list(getattr(ctx, "_declared_secrets", {}).values()) if getattr(
|
|
39
|
+
ctx, "_declared_secrets", None
|
|
40
|
+
) else []
|
|
41
|
+
|
|
42
|
+
# Try to fetch live is_set state per declared name (cheap meta read).
|
|
43
|
+
statuses: dict[str, dict] = {}
|
|
44
|
+
if hasattr(ctx, "secrets") and ctx.secrets is not None:
|
|
45
|
+
try:
|
|
46
|
+
live = await ctx.secrets.list()
|
|
47
|
+
for s in live:
|
|
48
|
+
# SecretStatus or dict — handle both.
|
|
49
|
+
name = getattr(s, "name", None) or (s.get("name") if isinstance(s, dict) else None)
|
|
50
|
+
if name is None:
|
|
51
|
+
continue
|
|
52
|
+
statuses[name] = {
|
|
53
|
+
"is_set": bool(getattr(s, "is_set", None) if not isinstance(s, dict) else s.get("is_set", False)),
|
|
54
|
+
"last_accessed_at": (
|
|
55
|
+
getattr(s, "last_accessed_at", None)
|
|
56
|
+
if not isinstance(s, dict)
|
|
57
|
+
else s.get("last_accessed_at")
|
|
58
|
+
),
|
|
59
|
+
}
|
|
60
|
+
except Exception:
|
|
61
|
+
statuses = {}
|
|
62
|
+
|
|
63
|
+
cards = []
|
|
64
|
+
for spec in declared:
|
|
65
|
+
name = getattr(spec, "name", None) or (spec.get("name") if isinstance(spec, dict) else None)
|
|
66
|
+
if not name:
|
|
67
|
+
continue
|
|
68
|
+
desc = getattr(spec, "description", "") or (spec.get("description", "") if isinstance(spec, dict) else "")
|
|
69
|
+
write_mode = (
|
|
70
|
+
getattr(spec, "write_mode", "user")
|
|
71
|
+
if not isinstance(spec, dict)
|
|
72
|
+
else spec.get("write_mode", "user")
|
|
73
|
+
)
|
|
74
|
+
status = statuses.get(name, {"is_set": False, "last_accessed_at": None})
|
|
75
|
+
is_set = bool(status.get("is_set"))
|
|
76
|
+
last_read = status.get("last_accessed_at")
|
|
77
|
+
|
|
78
|
+
# One card per secret with status + Manage button.
|
|
79
|
+
rows = [ui.Text(desc) if desc else None]
|
|
80
|
+
if is_set:
|
|
81
|
+
rows.append(ui.Badge("Set", color="green"))
|
|
82
|
+
if last_read:
|
|
83
|
+
rows.append(ui.Text(f"Last read: {last_read}", color="muted"))
|
|
84
|
+
else:
|
|
85
|
+
rows.append(ui.Badge("Not set", color="gray"))
|
|
86
|
+
if write_mode == "extension":
|
|
87
|
+
rows.append(ui.Text("(extension-write only — written after authorize)", color="muted"))
|
|
88
|
+
|
|
89
|
+
rows.append(ui.Button(
|
|
90
|
+
label="Manage" if is_set else "Set value",
|
|
91
|
+
variant="primary" if not is_set else "secondary",
|
|
92
|
+
on_click=ui.Navigate(path=f"/ext/{ext_id}/secrets#{name}"),
|
|
93
|
+
))
|
|
94
|
+
|
|
95
|
+
cards.append(ui.Card(
|
|
96
|
+
title=name,
|
|
97
|
+
content=ui.Stack(children=[r for r in rows if r is not None]),
|
|
98
|
+
))
|
|
99
|
+
|
|
100
|
+
if not cards:
|
|
101
|
+
cards.append(ui.Card(
|
|
102
|
+
title="No secrets declared",
|
|
103
|
+
content=ui.Stack(children=[
|
|
104
|
+
ui.Text(
|
|
105
|
+
"This extension does not declare any secrets. If you are "
|
|
106
|
+
"the developer, add an @ext.secret(...) declaration to "
|
|
107
|
+
"your app.py and redeploy."
|
|
108
|
+
),
|
|
109
|
+
ui.Link(
|
|
110
|
+
text="Read @ext.secret reference →",
|
|
111
|
+
href="https://docs.imperal.io/en/sdk/decorator-secret-reference/",
|
|
112
|
+
),
|
|
113
|
+
]),
|
|
114
|
+
))
|
|
115
|
+
|
|
116
|
+
root = ui.Stack(children=[
|
|
117
|
+
ui.Heading(f"Secrets · {ext_id}", level=2),
|
|
118
|
+
ui.Text(
|
|
119
|
+
"Credentials this extension needs — API keys, OAuth tokens. "
|
|
120
|
+
"Stored encrypted in Vault; never visible to admins or in logs."
|
|
121
|
+
),
|
|
122
|
+
*cards,
|
|
123
|
+
ui.Link(
|
|
124
|
+
text=f"Open full Secrets manager →",
|
|
125
|
+
href=f"/ext/{ext_id}/secrets",
|
|
126
|
+
),
|
|
127
|
+
])
|
|
128
|
+
|
|
129
|
+
# Match the wrapper contract from @ext.panel decorator — return .to_dict()
|
|
130
|
+
# of the root. The kernel wraps {"ui": ..., "panel_id": "secrets"}.
|
|
131
|
+
if hasattr(root, "to_dict"):
|
|
132
|
+
return root.to_dict()
|
|
133
|
+
return root
|
|
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-4.2.2 → imperal_sdk-4.2.4}/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-4.2.2 → imperal_sdk-4.2.4}/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
|
|
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
|