Files
inter-hub/Application/Helper/ModelRouter.hs
Bernd Worsch 74bab5f6f2 fix(WP-0014/A2): continued type-correctness fixes and Tailwind CSS output
- Schema.sql: add FK constraints for phases 6–12 so IHP generates Id X
  instead of UUID for FK columns (widget_adapter_specs, friction_scores,
  hub_routing_rules, agent_proposals, hub_capability_manifests, etc.)
- HubHealth, ModelRouter, ApiInteractionEvents: remove toUUID() wrappers
  now that FK columns carry proper Id types
- FederatedGovernance/Dashboard, HubRoutingRules/Index: same Id comparison fix
- AgentProposals/Index, DecisionRecords/Index, ApiConsumers/Edit: Id type fixes
- BottleneckDetector: add Data.Coerce import; CrossHubPropagation: add guard
- ApiKeys: qualify cryptohash-sha256 import to resolve package ambiguity
- WebhookDeliveryJob: use LBS.fromStrict; remove duplicate diffUTCTime
- Sessions/New: use renderFlashMessages (IHP built-in)
- ArchiveRecords/LineageInspector: simplify renderChainStep signature
- static/app.css: Tailwind CSS output (2011 lines) — A3 confirmed
- workplans/IHUB-WP-0015-local-deployment-intro-ui.md: add workplan

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 01:49:41 +00:00

43 lines
1.6 KiB
Haskell

module Application.Helper.ModelRouter where
-- IHF Phase 11 — Advanced AI Federation (IHUB-WP-0012 T04)
-- Resolve the AgentRegistration to use for a hub + task type.
import IHP.Prelude
import IHP.ControllerPrelude
import Generated.Types
import Web.Routes ()
import Database.PostgreSQL.Simple (Only(..))
-- | Resolve the highest-priority active AgentRegistration for the given hub
-- and task type. Returns Nothing if no matching policy exists (callers should
-- fall back gracefully or surface an error to the operator).
resolveAgent ::
(?modelContext :: ModelContext) =>
Id Hub -> Text -> IO (Maybe AgentRegistration)
resolveAgent hubId taskType = do
rows <- sqlQuery
"SELECT mrp.agent_registration_id \
\ FROM model_routing_policies mrp \
\ WHERE mrp.hub_id = ? AND mrp.task_type = ? AND mrp.is_active = TRUE \
\ ORDER BY mrp.priority DESC \
\ LIMIT 1"
(hubId, taskType)
case rows of
[Only (agentId :: Id AgentRegistration)] -> fetchOneOrNothing agentId
_ -> pure Nothing
-- | Return all active AgentRegistrations for a hub + task_type ordered by
-- priority (highest first). Used by CollectiveProposals to fan out.
resolveAllAgents ::
(?modelContext :: ModelContext) =>
Id Hub -> Text -> IO [AgentRegistration]
resolveAllAgents hubId taskType = do
rows <- sqlQuery
"SELECT mrp.agent_registration_id \
\ FROM model_routing_policies mrp \
\ WHERE mrp.hub_id = ? AND mrp.task_type = ? AND mrp.is_active = TRUE \
\ ORDER BY mrp.priority DESC"
(hubId, taskType)
mapM (\(Only (i :: Id AgentRegistration)) -> fetch i) rows