Skip to content

Release v3.2.0

Choose a tag to compare

@github-actions github-actions released this 23 Sep 20:01
6749a47

Summary

Decision Making joins the generative capabilities as a first-class AI capability. A caller supplies a context and a finite set of outcomes; the provider returns a probability distribution over exactly those outcomes. Nothing is generated.

It also adds the Decision Engine service itself — a small CPU-first inference service — under Source/DecisionEngine/.

Added

  • IDecisions — submit context plus a finite set of choices, get back every choice with its probability, the highest-probability choice, and the margin to the runner-up. Thresholds are deliberately left to consumers so the raw distribution survives intact (#392)
  • A batch overload on IDecisions for callers scoring many candidates against one task, with results guaranteed in request order (#392)
  • Decision as an AIProviderCapability and an AIModelCapability, advertised independently of the conversational and agentic capabilities (#392)
  • AIProviderType.DecisionEngine and AddDecisionEngineProvider / ReconfigureDecisionEngineProvider for configuring decision providers the same way as any other AI provider (#392)
  • AIModelCapabilities.For(AIProviderType, ModelName) — capability for a decision model is declared by provider type rather than inferred from the model identifier, which carries no marker that would distinguish it from a chat model (#392)
  • AIProviderCapabilities — what each provider type can be used for. A decision engine advertises Decision and neither Conversational nor Agentic, so existing compatibility checks refuse to schedule an agent onto it (#392)
  • AddCratisAI(ai => ai.WithDecisions<TResolver>()) registers the decision surface. Nothing decision-related is registered when it is not called (#392)
  • Telemetry on Cratis.AI.Decisions: decision duration, count, and top-probability distribution. Context text is not recorded unless explicitly enabled (#392)
  • The Cratis Decision Engine service under Source/DecisionEngine/ — Decision API v1, CPU-first, model and calibration temperature configurable, with an artifact cache so restarts do not re-download weights (#392)

Changed

  • ConfiguredAIProvider now projects the Decision Engine provider events (#392)

Notes for reviewers

Three enums gained a member and all three are persisted in events — appended, never renumbered. AIProviderCapability.Decision = 2, AIModelCapability.Decision = 4, AIProviderType.DecisionEngine = 6.

Why scoring rather than generating. The service scores each choice by mean per-token log-likelihood conditioned on a prompt that includes the full option set, then softmaxes. Asking a 0.5B model to emit the answer would give one label and a self-reported confidence worth nothing; scoring gives a real distribution for one short forward pass per choice. Mean rather than summed log-likelihood, or longer choices would lose on length alone.

What is deliberately absent. No thresholds, no fallback, no retry policy anywhere in this package — those differ per workflow, and centralizing them would both force one answer on every consumer and destroy the signal that later calibration depends on.

Verification. dotnet build -c Release clean; dotnet test 292/292 passing (Cratis.AI.Specs); pytest 20/20 passing (Source/DecisionEngine). The service has not yet been run against real weights — that happens in Cratis/Infrastructure#58, where it is deployed and benchmarked.