Releases: aiperceivable/apcore-python
Releases · aiperceivable/apcore-python
Release 0.17.1
Added
build_minimal_strategy()— 4-step pipeline (context → lookup → execute → return) for pre-validated internal hot paths. Registered as"minimal"in Executor preset builders.requires/providesonBaseStep— Optional advisory fields declaring step dependencies.ExecutionStrategyvalidates dependency chains at construction and insertion, emitting warnings for unmetrequires.
Fixed
"minimal"added to preset builders —Executor(strategy="minimal")now works. Previously missing from_resolve_strategy_name()preset dict.- Executor docstrings updated — Constructor and
_resolve_strategy_namedocstrings now list all 5 presets (was missing"minimal").
Release 0.17.0
Added
- Step Metadata: Four declarative fields on
BaseStep:match_modules(glob patterns for selective execution),ignore_errors(fault-tolerant steps),pure(safe forvalidate()dry-run),timeout_ms(per-step timeout). - YAML Pipeline Configuration:
register_step_type(),unregister_step_type(),registered_step_types(),build_strategy_from_config()— configure pipeline steps viaapcore.yamlat startup. - PipelineContext fields:
dry_run,version_hint,executed_middlewaresfor pipeline-aware execution. - StepTrace:
skip_reasonfield for understanding why steps were skipped ("no_match", "dry_run", "error_ignored").
Changed
- Step order:
middleware_beforenow runs BEFOREinput_validation(was after). Middleware input transforms are now validated by the schema check. - Executor delegation:
call(),call_async(),validate(), andstream()fully delegate toPipelineEngine.run(). Removed ~300 lines of duplicated inline step code. - Renamed:
safety_checkstep →call_chain_guard(accurately describes call-chain depth/cycle/repeat checking). - Renamed:
BuiltinSafetyCheckclass →BuiltinCallChainGuard.
Fixed
- Middleware input transforms were never re-validated against the schema (now validated after middleware runs).
validate()was hardcoded to 7 inline checks; now usesdry_run=Truepipeline mode — user-addedpure=Truesteps automatically participate.
Release 0.16.0
Added
- Config Bus:
env_style(auto/nested/flat),max_depth,env_prefixauto-derivation,env_map(namespace + global),Config.env_map(),CONFIG_ENV_MAP_CONFLICTerror. - Context:
ContextKey[T]typed accessor withget()/set()/delete()/exists()/scoped(). Built-in key constants (TRACING_SPANS,METRICS_STARTS, etc.).Context.serialize()/deserialize()with_context_version: 1. - Annotations:
extra: dict[str, Any]extension field onModuleAnnotations.pagination_stylechanged fromLiteraltostr.DEFAULT_ANNOTATIONSconstant.from_dict()classmethod with unknown key capture. - ACL:
SyncACLConditionHandler/AsyncACLConditionHandlerprotocols.ACL.register_condition().$or/$notcompound operators.async_check()method. Fail-closed for unknown conditions. - Pipeline:
Stepprotocol,BaseStepABC,StepResult,PipelineContext,PipelineTrace,ExecutionStrategy,PipelineEngine. 11BuiltinStepclasses. Preset strategies (standard/internal/testing/performance).Executor.strategyparameter.call_with_trace()/call_async_with_trace().register_strategy()/list_strategies()/describe_pipeline().
Changed
- Middleware data keys migrated from legacy names (
_metrics_startsetc.) to_apcore.mw.*convention using typedContextKey.
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