Skip to content

Releases: aiperceivable/apcore-python

Release 0.17.1

06 Apr 04:59

Choose a tag to compare

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 / provides on BaseStep — Optional advisory fields declaring step dependencies. ExecutionStrategy validates dependency chains at construction and insertion, emitting warnings for unmet requires.

Fixed

  • "minimal" added to preset buildersExecutor(strategy="minimal") now works. Previously missing from _resolve_strategy_name() preset dict.
  • Executor docstrings updated — Constructor and _resolve_strategy_name docstrings now list all 5 presets (was missing "minimal").

Release 0.17.0

05 Apr 11:30

Choose a tag to compare

Added

  • Step Metadata: Four declarative fields on BaseStep: match_modules (glob patterns for selective execution), ignore_errors (fault-tolerant steps), pure (safe for validate() 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 via apcore.yaml at startup.
  • PipelineContext fields: dry_run, version_hint, executed_middlewares for pipeline-aware execution.
  • StepTrace: skip_reason field for understanding why steps were skipped ("no_match", "dry_run", "error_ignored").

Changed

  • Step order: middleware_before now runs BEFORE input_validation (was after). Middleware input transforms are now validated by the schema check.
  • Executor delegation: call(), call_async(), validate(), and stream() fully delegate to PipelineEngine.run(). Removed ~300 lines of duplicated inline step code.
  • Renamed: safety_check step → call_chain_guard (accurately describes call-chain depth/cycle/repeat checking).
  • Renamed: BuiltinSafetyCheck class → 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 uses dry_run=True pipeline mode — user-added pure=True steps automatically participate.

Release 0.16.0

05 Apr 03:30

Choose a tag to compare

Added

  • Config Bus: env_style (auto/nested/flat), max_depth, env_prefix auto-derivation, env_map (namespace + global), Config.env_map(), CONFIG_ENV_MAP_CONFLICT error.
  • Context: ContextKey[T] typed accessor with get()/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 on ModuleAnnotations. pagination_style changed from Literal to str. DEFAULT_ANNOTATIONS constant. from_dict() classmethod with unknown key capture.
  • ACL: SyncACLConditionHandler / AsyncACLConditionHandler protocols. ACL.register_condition(). $or/$not compound operators. async_check() method. Fail-closed for unknown conditions.
  • Pipeline: Step protocol, BaseStep ABC, StepResult, PipelineContext, PipelineTrace, ExecutionStrategy, PipelineEngine. 11 BuiltinStep classes. Preset strategies (standard/internal/testing/performance). Executor.strategy parameter. call_with_trace()/call_async_with_trace(). register_strategy()/list_strategies()/describe_pipeline().

Changed

  • Middleware data keys migrated from legacy names (_metrics_starts etc.) to _apcore.mw.* convention using typed ContextKey.

Release 0.15.1

31 Mar 10:11

Choose a tag to compare

Changed

  • Env prefix convention simplified — Removed the ^APCORE_[A-Z0-9] reservation rule from Config._validate_env_prefix(). Sub-packages now use single-underscore prefixes (APCORE_MCP, APCORE_OBSERVABILITY, APCORE_SYS) instead of the double-underscore form. Only the exact APCORE prefix is reserved for the core namespace.
  • Built-in namespace env prefixes: APCORE__OBSERVABILITYAPCORE_OBSERVABILITY, APCORE__SYSAPCORE_SYS.

Release 0.15.0

31 Mar 06:43

Choose a tag to compare

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 all Config instances. Late registration is allowed; call config.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; bind returns a view of the namespace deserialized into type, get_typed deserializes 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). _config is 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-underscore APCORE_ prefix used for flat keys.
  • Hot-reload namespace supportconfig.reload() re-reads YAML, re-detects mode, re-applies namespace defaults and env overrides, re-validates, and re-reads mounted files.
  • New error codesCONFIG_NAMESPACE_DUPLICATE, CONFIG_NAMESPACE_RESERVED, CONFIG_ENV_PREFIX_CONFLICT, CONFIG_MOUNT_ERROR, CONFIG_BIND_ERROR

Error Formatter Registry (§8.8)

  • ErrorFormatter protocol — Interface for adapter-specific error formatters. Implementations transform ModuleError into 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 surface
  • ErrorFormatterRegistry.get(surface) — retrieve a registered formatter
  • ErrorFormatterRegistry.format(surface, error) — format an error, falling back to error.to_dict() if no formatter is registered for that surface
  • New error codeERROR_FORMATTER_DUPLICATE

Built-in Namespace Registrations (§9.15)

  • observability namespace (APCORE__OBSERVABILITY env prefix) — apcore pre-registers this namespace, promoting the existing apcore.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_modules namespace (APCORE__SYS env prefix) — apcore pre-registers this namespace, promoting the existing apcore.sys_modules.* flat keys into a named subtree. register_sys_modules() prefers config.namespace("sys_modules") in namespace mode with config.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 into apcore.module.toggled (toggle on/off) and apcore.health.recovered (error rate recovery)
  • "config_changed" (previously used for both key updates and module reload) split into apcore.config.updated (runtime key update via system.control.update_config) and apcore.module.reloaded (hot-reload via system.control.reload_module)
  • Naming conventionapcore.* 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

25 Mar 02:09

Choose a tag to compare

Added

  • Middleware priorityMiddleware base class now accepts priority: int (0-1000, default 0). Higher priority executes first; equal priority preserves registration order. BeforeMiddleware and AfterMiddleware adapters also accept priority.
  • Priority range validationValueError raised for priority values outside 0-1000

Breaking Changes

  • Middleware default priority changed from 0 to 100 per PROTOCOL_SPEC §11.2. Middleware without explicit priority will now execute before priority-0 middleware.

Release 0.13.2

22 Mar 12:51

Choose a tag to compare

Changed

  • Rebrand: aipartnerup → aiperceivable

Release 0.13.1

19 Mar 07:32

Choose a tag to compare

Added

  • Dict schema support — Modules can now define input_schema / output_schema as plain JSON Schema dicts instead of Pydantic model classes. A _DictSchemaAdapter transparently 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, causing AttributeError
  • Executor crash on dict schemascall(), call_async(), and stream() all called .model_validate() on dict objects

Improved

  • File header docstrings — Enhanced docstrings for errors.py, executor.py, and version.py

Release 0.13.0

12 Mar 06:49

Choose a tag to compare

Added

  • Caching/pagination annotationsModuleAnnotations gains 5 new fields: cacheable, cache_ttl, cache_key_fields, paginated, pagination_style (all optional with defaults, backward compatible)
  • pagination_style Literal type — Typed as Literal["cursor", "offset", "page"] instead of free-form str
  • sunset_date — New field on ModuleDescriptor for module deprecation lifecycle (ISO 8601 date)
  • on_suspend() / on_resume() lifecycle hooks — Duck-typed optional hooks for state preservation during hot-reload; integrated into ReloadModuleModule and registry watchdog
  • MCP _meta export — Schema exporter includes cacheable, cacheTtl, cacheKeyFields, paginated, paginationStyle in _meta sub-dict
  • Suspend/resume teststests/test_suspend_resume.py covering state transfer, backward compatibility, error handling

Changed

  • Rebranded — "module development framework" → "module standard" in pyproject.toml, __init__.py, README, and internal docstrings
  • Module Protocolon_suspend/on_resume deliberately kept OUT of Protocol (duck-typed via hasattr/callable)

Release 0.12.0

11 Mar 08:26

Choose a tag to compare

Changed

  • ExecutionCancelledError now extends ModuleError (was bare Exception) with error code EXECUTION_CANCELLED, aligning with PROTOCOL_SPEC §8.7 error hierarchy
  • ErrorCodes — Added EXECUTION_CANCELLED constant