Releases: aiperceivable/apcore-python
Releases · aiperceivable/apcore-python
Release 0.15.1
Changed
- Env prefix convention simplified — Removed the
^APCORE_[A-Z0-9]reservation rule fromConfig._validate_env_prefix(). Sub-packages now use single-underscore prefixes (APCORE_MCP,APCORE_OBSERVABILITY,APCORE_SYS) instead of the double-underscore form. Only the exactAPCOREprefix is reserved for the core namespace. - Built-in namespace env prefixes:
APCORE__OBSERVABILITY→APCORE_OBSERVABILITY,APCORE__SYS→APCORE_SYS.
Release 0.15.0
Added
Config Bus Architecture (§9.4–§9.14)
Config.register_namespace(name, schema=None, env_prefix=None, defaults=None)— Class-level namespace registration. Any package can claim a named config subtree with optional JSON Schema validation, env prefix, and default values. Global registry is shared across allConfiginstances. Late registration is allowed; callconfig.reload()afterward to apply defaults and env overrides.config.get("namespace.key.path")— Dot-path access with namespace resolution. First segment resolves to a registered namespace; remaining segments traverse the subtree.config.namespace(name)— Returns the full config subtree for a registered namespace as a dict.config.bind(ns, type)/config.get_typed(path, type)— Typed namespace access;bindreturns a view of the namespace deserialized intotype,get_typeddeserializes a single dot-path value.config.mount(namespace, from_file=...|from_dict=...)— Attach external config sources to a namespace without a unified YAML file. Primary integration path for third-party packages with existing config systems.Config.registered_namespaces()— Class-level introspection; returns names of all registered namespaces.- Unified YAML with namespace partitioning — Single YAML file with namespace-keyed top-level sections. Automatic mode detection: legacy mode (no
apcore:key, fully backward compatible) vs. namespace mode (apcore:key present)._configis a reserved meta-namespace (strict,allow_unknown). - Per-namespace env override with longest-prefix-match dispatch — Each namespace declares its own
env_prefix.APCORE__double-underscore convention for apcore sub-packages (e.g.,APCORE__OBSERVABILITY,APCORE__SYS) to avoid collision with the existing single-underscoreAPCORE_prefix used for flat keys. - Hot-reload namespace support —
config.reload()re-reads YAML, re-detects mode, re-applies namespace defaults and env overrides, re-validates, and re-reads mounted files. - New error codes —
CONFIG_NAMESPACE_DUPLICATE,CONFIG_NAMESPACE_RESERVED,CONFIG_ENV_PREFIX_CONFLICT,CONFIG_MOUNT_ERROR,CONFIG_BIND_ERROR
Error Formatter Registry (§8.8)
ErrorFormatterprotocol — Interface for adapter-specific error formatters. Implementations transformModuleErrorinto the surface-specific wire format (e.g., MCP camelCase, JSON-RPC code mapping).ErrorFormatterRegistry— Shared registry for surface-specific formatters:ErrorFormatterRegistry.register(surface, formatter)— register a formatter for a named surfaceErrorFormatterRegistry.get(surface)— retrieve a registered formatterErrorFormatterRegistry.format(surface, error)— format an error, falling back toerror.to_dict()if no formatter is registered for that surface- New error code —
ERROR_FORMATTER_DUPLICATE
Built-in Namespace Registrations (§9.15)
observabilitynamespace (APCORE__OBSERVABILITYenv prefix) — apcore pre-registers this namespace, promoting the existingapcore.observability.*flat config keys (tracing, metrics, logging, error_history, platform_notify) into a named subtree. Adapter packages (apcore-mcp, apcore-a2a, apcore-cli) should read from this namespace rather than independent logging defaults.sys_modulesnamespace (APCORE__SYSenv prefix) — apcore pre-registers this namespace, promoting the existingapcore.sys_modules.*flat keys into a named subtree.register_sys_modules()prefersconfig.namespace("sys_modules")in namespace mode withconfig.get("sys_modules.*")legacy fallback. Both registrations are 1:1 migrations of existing keys; there are no breaking changes.
Event Type Naming Convention and Collision Fix (§9.16)
- Canonical event names — Two confirmed event type collisions in apcore-python are resolved:
"module_health_changed"(previously used for both enable/disable toggles and error-rate recovery) split intoapcore.module.toggled(toggle on/off) andapcore.health.recovered(error rate recovery)"config_changed"(previously used for both key updates and module reload) split intoapcore.config.updated(runtime key update viasystem.control.update_config) andapcore.module.reloaded(hot-reload viasystem.control.reload_module)- Naming convention —
apcore.*is reserved for core framework events. Adapter packages use their own prefix:apcore-mcp.*,apcore-a2a.*,apcore-cli.*. - Transition aliases — All four legacy short-form names (
module_health_changed,config_changed) continue to be emitted alongside the canonical names during the transition period.
Release 0.14.0
Added
- Middleware priority —
Middlewarebase class now acceptspriority: int(0-1000, default 0). Higher priority executes first; equal priority preserves registration order.BeforeMiddlewareandAfterMiddlewareadapters also acceptpriority. - Priority range validation —
ValueErrorraised for priority values outside 0-1000
Breaking Changes
- Middleware default priority changed from
0to100per PROTOCOL_SPEC §11.2. Middleware without explicit priority will now execute before priority-0 middleware.
Release 0.13.2
Changed
- Rebrand: aipartnerup → aiperceivable
Release 0.13.1
Added
- Dict schema support — Modules can now define
input_schema/output_schemaas plain JSON Schema dicts instead of Pydantic model classes. A_DictSchemaAdaptertransparently wraps dict schemas at registration time so all internal code paths (executor, schema exporter,get_definition) work without changes.
Fixed
get_definition()crash on dict schemas — Previously called.model_json_schema()on dict objects, causingAttributeError- Executor crash on dict schemas —
call(),call_async(), andstream()all called.model_validate()on dict objects
Improved
- File header docstrings — Enhanced docstrings for
errors.py,executor.py, andversion.py
Release 0.13.0
Added
- Caching/pagination annotations —
ModuleAnnotationsgains 5 new fields:cacheable,cache_ttl,cache_key_fields,paginated,pagination_style(all optional with defaults, backward compatible) pagination_styleLiteral type — Typed asLiteral["cursor", "offset", "page"]instead of free-formstrsunset_date— New field onModuleDescriptorfor module deprecation lifecycle (ISO 8601 date)on_suspend()/on_resume()lifecycle hooks — Duck-typed optional hooks for state preservation during hot-reload; integrated intoReloadModuleModuleand registry watchdog- MCP
_metaexport — Schema exporter includescacheable,cacheTtl,cacheKeyFields,paginated,paginationStylein_metasub-dict - Suspend/resume tests —
tests/test_suspend_resume.pycovering state transfer, backward compatibility, error handling
Changed
- Rebranded — "module development framework" → "module standard" in pyproject.toml,
__init__.py, README, and internal docstrings ModuleProtocol —on_suspend/on_resumedeliberately kept OUT of Protocol (duck-typed viahasattr/callable)
Release 0.12.0
Changed
ExecutionCancelledErrornow extendsModuleError(was bareException) with error codeEXECUTION_CANCELLED, aligning with PROTOCOL_SPEC §8.7 error hierarchyErrorCodes— AddedEXECUTION_CANCELLEDconstant
Release 0.11.0
Added
- Full lifecycle integration tests (
tests/integration/test_full_lifecycle.py) — 8 tests covering the complete 11-step pipeline with all gates (ACL + Approval + Middleware + Schema validation) enabled simultaneously, nested module calls, sharedcontext.data, error propagation, and ACL conditions.
System Modules — AI Bidirectional Introspection
Built-in system.* modules that allow AI agents to query, monitor
system.health.summary— Aggregate health status across all registered modules (healthy/degraded/unhealthy classification based on error rate thresholds).system.health.module— Per-module health detail including recent errors fromErrorHistory.system.manifest.module— Single module introspection (schema, annotations, tags, source path).system.manifest.full— Full registry manifest with filtering by tags/prefix.system.usage.summary— Usage statistics across all modules (call counts, error rates, avg latency).system.usage.module— Per-module usage detail with hourly trend data.system.control.update_config— Runtime config hot-patching with constraint validation.system.control.reload_module— Hot-reload a module from disk without restart.system.control.toggle_feature— Enable/disable modules at runtime with reason tracking.register_sys_modules()— Auto-registration wiring for all system modules.
Observability
ErrorHistory— Ring buffer tracking recent errors with deduplication and per-module querying.ErrorHistoryMiddleware— Middleware that recordsModuleErrordetails intoErrorHistory.UsageCollector— Per-module call counting, latency histograms, and hourly bucketed trend data.PlatformNotifyMiddleware— Threshold-based sensor that emits events on error rate spikes.
Event System
EventEmitter— Global event bus with async subscriber dispatch and thread-pool execution.EventSubscriberprotocol — Interface for event consumers.ApCoreEvent— Frozen dataclass for typed events (module lifecycle, errors, config changes).WebhookSubscriber— HTTP POST event delivery with retry.A2ASubscriber— Agent-to-Agent protocol event bridge.
APCore Unified Client
APCore.on()/APCore.off()— Event subscription management via the unified client.APCore.disable()/APCore.enable()— Module toggle control via the unified client.APCore.discover()/APCore.list_modules()— Discovery and listing via the unified client.
Public API Exports
ModuleDisabledError— Error class forMODULE_DISABLEDcode, raised when a disabled module is called.ReloadFailedError— Error class forRELOAD_FAILEDcode (retryable).SchemaStrategy— Enum for schema resolution strategy (yaml_first,native_first,yaml_only).ExportProfile— Enum for schema export profiles (mcp,openai,anthropic,generic).
Registry
- Module toggle — APCore client now supports
disable()/enable()for module toggling viasystem.control.toggle_feature, withModuleDisabledErrorenforcement and event emission. - Version negotiation —
negotiate_version()for SDK/module version compatibility checking.
Changed
WebhookSubscriber/A2ASubscribernow require optional dependencyaiohttp. Install withpip install apcore[events]. Core SDK no longer fails to import whenaiohttpis not installed.
Fixed
aiohttphard import inevents/subscribers.pybroke core SDK import whenaiohttpwas not installed. Changed totry/except ImportErrorguard with clear error message at runtime.A2ASubscriber.on_eventImportErrorfor missingaiohttpwas silently swallowed by the broadexcept Exceptionblock. Moved guard before thetryblock to surface the error correctly.- README Access Control example now includes required
ExecutorandRegistryimports. pyproject.tomlrepository/issues/changelog URLs now point toapcore-python(was incorrectly pointing toapcore).- CHANGELOG
[0.7.1]compare link added (was missing from link references).
Release 0.10.0
Added
APCore Unified Client
APCore.stream()— Stream module output chunk by chunk via the unified client.APCore.validate()— Non-destructive preflight check via the unified client.APCore.describe()— Get module description info (for AI/LLM use).APCore.use_before()— Add before function middleware via the unified client.APCore.use_after()— Add after function middleware via the unified client.APCore.remove()— Remove middleware by identity via the unified client.
Global Entry Points (apcore.*)
apcore.stream()— Global convenience for streaming module calls.apcore.validate()— Global convenience for preflight validation.apcore.register()— Global convenience for direct module registration.apcore.describe()— Global convenience for module description.apcore.use()— Global convenience for adding middleware.apcore.use_before()— Global convenience for adding before middleware.apcore.use_after()— Global convenience for adding after middleware.apcore.remove()— Global convenience for removing middleware.
Error Hierarchy
FeatureNotImplementedError— New error class forGENERAL_NOT_IMPLEMENTEDcode (renamed fromNotImplementedErrorto avoid Python stdlib clash).DependencyNotFoundError— New error class forDEPENDENCY_NOT_FOUNDcode.
Changed
- APCore client and
apcore.*global functions now provide full feature parity withExecutor.
Release 0.9.0
Added
Enhanced Executor.validate() Preflight
PreflightCheckResult— New frozen dataclass representing a single preflight check result withcheck,passed, anderrorfields.PreflightResult— New dataclass returned byExecutor.validate(), containing per-check results andrequires_approvalflag. Duck-type compatible withValidationResultvia.validand.errorsproperties.- Full 6-check preflight —
validate()now runs Steps 1–6 of the pipeline (module_id format, module lookup, call chain safety, ACL, approval detection, schema validation) without executing module code or middleware.
Changed
Executor Pipeline
- Step renumbering — Approval Gate renumbered from Step 4.5 to Step 5; all subsequent steps shifted +1 (now 11 clean steps).
validate()return type — Changed fromValidationResulttoPreflightResult. Backward compatible:.validand.errorsstill work identically for existing consumers (e.g., apcore-mcp router).validate()signature — Added optionalcontextparameter for call-chain checks;inputsnow defaults to{}.
Public API
- Exported
PreflightCheckResultandPreflightResultfromapcoretop-level package.