generated from coulomb/repo-seed
feat(WP-0012): IHF Phase 11 — Advanced AI Federation
Some checks failed
Test / test (push) Has been cancelled
Some checks failed
Test / test (push) Has been cancelled
- Schema: AgentRegistration, ModelRoutingPolicy, AgentDelegation, CollectiveProposal, CollectiveProposalContribution, AiGovernancePolicy, AgentPerformanceRecord + ALTER TABLE agent_proposals (migration 1744156800; CHECK constraints on trust_level, status, consensus_status — GAAF compliant) - Bridge: scripts/llm_bridge.py (llm-connect subprocess seam) + Application/Helper/AgentBridge.hs (callBridge, callAgent, checkGovernancePolicy, jsonArrayTexts) - Routing: Application/Helper/ModelRouter.hs (resolveAgent, resolveAllAgents) + ModelRoutingPolicies CRUD - Registry: AgentRegistrations CRUD (Index/Show/New/Edit/Performance), DeactivateAgentAction, ComputeAgentPerformanceAction - Delegation: AgentDelegations controller + views, DelegateSubtaskAction with token budget enforcement at bridge call time - Collective: CollectiveProposals controller + views, CreateCollectiveProposalAction (fan-out → synthesis → consensus detection) - Governance: AiGovernancePolicies CRUD + ToggleAiGovernancePolicyAction; checkGovernancePolicy enforced at all 4 Phase 5 invocation points - Phase 5 wiring: replaced callClaudeApi in Widgets, DecisionRecords, RequirementCandidates with resolveAgent + callAgent + token tracking - llm-connect feature requests: ~/llm-connect/FEATURE_REQUESTS.md (FR-1 HTTP serve, FR-2 RoutingPolicy, FR-3 async, FR-4 BudgetTracker) - GAAF scorecard: 3.61 (up from 3.56); Functional 3.4→3.6, Extensions 3.8→3.9 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,8 @@ import Web.View.DecisionRecords.Edit
|
||||
import Generated.Types
|
||||
import IHP.Prelude
|
||||
import IHP.ControllerPrelude
|
||||
import Application.Helper.Controller (callClaudeApi)
|
||||
import Application.Helper.AgentBridge (callAgent, checkGovernancePolicy)
|
||||
import Application.Helper.ModelRouter (resolveAgent)
|
||||
import Data.List (intercalate)
|
||||
|
||||
validOutcomes :: [Text]
|
||||
@@ -178,7 +179,7 @@ instance Controller DecisionRecordsController where
|
||||
setSuccessMessage "Implementation reference removed"
|
||||
redirectTo ShowDecisionRecordAction { decisionRecordId }
|
||||
|
||||
-- T07: Propose implementation paths via Claude API
|
||||
-- T07 / Phase 11: Propose implementation paths via routed agent
|
||||
action ProposeImplementationAction { decisionRecordId } = do
|
||||
record <- fetch decisionRecordId
|
||||
implRefs <- query @ImplementationChangeReference
|
||||
@@ -187,6 +188,10 @@ instance Controller DecisionRecordsController where
|
||||
mRequirement <- case record.requirementId of
|
||||
Nothing -> pure Nothing
|
||||
Just rid -> fetchOneOrNothing rid
|
||||
-- Resolve hub from the source widget via requirement candidate
|
||||
mHubId <- case mRequirement >>= (.sourceWidgetId) of
|
||||
Nothing -> pure Nothing
|
||||
Just wid -> fmap (.hubId) <$> fetchOneOrNothing @Widget wid
|
||||
let implLines = map (\r -> r.system <> ": " <> r.workItemRef) implRefs
|
||||
reqDesc = maybe "" (.description) mRequirement
|
||||
userMsg = "Decision: " <> record.title
|
||||
@@ -194,21 +199,46 @@ instance Controller DecisionRecordsController where
|
||||
<> "\nOutcome: " <> record.outcome
|
||||
<> "\nRequirement: " <> reqDesc
|
||||
<> "\nExisting impl refs: " <> intercalate ", " implLines
|
||||
result <- liftIO $ callClaudeApi
|
||||
"You are a traceability-aware implementation analyst. Propose 1\x20133 concrete implementation paths for this decision. Each path should include a work_item_ref (e.g. PROJ-123), a system (github|linear|jira), and a rationale. Respond with JSON: {\"proposals\": [{\"work_item_ref\": \"...\", \"system\": \"...\", \"rationale\": \"...\"}]}."
|
||||
userMsg
|
||||
600
|
||||
case result of
|
||||
Left err -> do
|
||||
setErrorMessage ("Implementation proposal failed: " <> err)
|
||||
redirectTo ShowDecisionRecordAction { decisionRecordId }
|
||||
Right content -> do
|
||||
newRecord @AgentProposal
|
||||
|> set #proposalType "impl_proposal"
|
||||
|> set #sourceDecisionId (Just decisionRecordId)
|
||||
|> set #content content
|
||||
|> set #modelRef "claude-sonnet-4-6"
|
||||
|> set #status "pending"
|
||||
|> createRecord
|
||||
setSuccessMessage "Implementation proposal created"
|
||||
case mHubId of
|
||||
Nothing -> do
|
||||
setErrorMessage "Cannot determine hub for routing — ensure the decision has a linked requirement with a source widget"
|
||||
redirectTo ShowDecisionRecordAction { decisionRecordId }
|
||||
Just hubId -> do
|
||||
mAgent <- resolveAgent hubId "implementation"
|
||||
case mAgent of
|
||||
Nothing -> do
|
||||
setErrorMessage "No routing policy for 'implementation' task type"
|
||||
redirectTo ShowDecisionRecordAction { decisionRecordId }
|
||||
Just agent -> do
|
||||
allowed <- checkGovernancePolicy hubId agent.id "decision_record"
|
||||
if not allowed
|
||||
then do
|
||||
newRecord @AgentProposal
|
||||
|> set #proposalType "impl_proposal"
|
||||
|> set #sourceDecisionId (Just decisionRecordId)
|
||||
|> set #content "Blocked by AI governance policy"
|
||||
|> set #modelRef agent.modelName
|
||||
|> set #status "blocked_by_policy"
|
||||
|> set #agentRegistrationId (Just agent.id)
|
||||
|> createRecord
|
||||
setErrorMessage "Blocked by AI governance policy"
|
||||
redirectTo ShowDecisionRecordAction { decisionRecordId }
|
||||
else do
|
||||
result <- liftIO $ callAgent agent userMsg
|
||||
case result of
|
||||
Left err -> do
|
||||
setErrorMessage ("Implementation proposal failed: " <> err.errorMessage)
|
||||
redirectTo ShowDecisionRecordAction { decisionRecordId }
|
||||
Right resp -> do
|
||||
newRecord @AgentProposal
|
||||
|> set #proposalType "impl_proposal"
|
||||
|> set #sourceDecisionId (Just decisionRecordId)
|
||||
|> set #content resp.content
|
||||
|> set #modelRef resp.modelUsed
|
||||
|> set #status "pending"
|
||||
|> set #agentRegistrationId (Just agent.id)
|
||||
|> set #tokensIn (Just resp.tokensIn)
|
||||
|> set #tokensOut (Just resp.tokensOut)
|
||||
|> createRecord
|
||||
setSuccessMessage "Implementation proposal created"
|
||||
redirectTo ShowDecisionRecordAction { decisionRecordId }
|
||||
|
||||
Reference in New Issue
Block a user