///|
/// Extension impl for RouterModelPort: declares RouterModelPort as a single
/// ModelPort contributor so the Agent's single-model cardinality constraint
/// is satisfied. The router internally manages multiple host-injected model
/// slots.

///|
pub impl @posoco.Extension for RouterModelPort with fn extension_id(
  _self : RouterModelPort,
) -> String {
  "posoco_ext_llm"
}

///|
pub impl @posoco.Extension for RouterModelPort with fn manifest(
  self : RouterModelPort,
) -> @posoco.ExtensionManifest {
  @posoco.ExtensionManifest(
    id="posoco_ext_llm",
    models=[self],
    observers=[self],
    lifecycle=[self],
    commands=[self],
    requires=[@posoco.Capability::Decision],
  )
}

///|
/// The `model` segment is resident: its initial state is knowable at
/// composition. `ctx` has no reading before core's first projection, so any
/// stale registration is unregistered instead of publishing a placeholder —
/// the segment first appears when a real reading arrives.
pub impl @posoco.Lifecycle for RouterModelPort with fn on_compose(
  self : RouterModelPort,
  ctx : @posoco.CompositionView,
) -> Unit raise @posoco.CompositionError {
  self.decision = ctx.decision()
  self.publish_model_status()
  self.publish_provider_event()
  match self.bus {
    Some(bus) =>
      @devkit.publish_status_unregister(
        bus,
        source="posoco_ext_llm",
        segment="ctx",
      )
    None => ()
  }
}

///|
pub extend RouterModelPort with @posoco.Lifecycle::{on_shutdown, on_start}

///|
/// Nothing to release: the router holds no resources beyond its slots.
pub impl @posoco.Lifecycle for RouterModelPort with fn on_shutdown(
  self : RouterModelPort,
) -> Unit {
  self.decision = None
}

///|
pub extend RouterModelPort with @posoco.Extension::{extension_id, manifest}