feat: integrate llm-connect FR-1/FR-3/FR-4 into IHF bridge
Some checks failed
Test / test (push) Has been cancelled

FR-3 (async_execute_prompt): CollectiveProposals now invokes all agents
concurrently via callAgentsBatch → single bridge subprocess with
asyncio.gather. Latency scales with slowest agent, not sum.

FR-4 (BudgetTracker): AgentDelegations passes tokenBudget to bridge;
llm-connect enforces it natively via BudgetTracker in RunConfig.
BudgetExceededError is a first-class BridgeError variant with total/
consumed/requested fields surfaced to the operator.

FR-1 (LLMServer passthrough): bridge accepts optional serverUrl field;
if present, calls POST {serverUrl}/execute instead of spawning a new
adapter. Infrastructure ready for hot-agent pre-warming (no schema
change required).

AgentBridge.hs: adds callAgentsBatch, callAgentWithBudget,
BudgetExceededError constructor, bridgeErrorMessage helper, defaultRequest,
requestToJson. All controllers updated to use bridgeErrorMessage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-01 22:48:29 +00:00
parent a400365d50
commit 674f5da0e1
7 changed files with 350 additions and 75 deletions

View File

@@ -11,7 +11,7 @@ import IHP.ControllerPrelude
import Data.Aeson (toJSON, object, (.=))
import Application.Helper.Controller (isInRegression, widgetCycleCounts)
import Application.Helper.TypeRegistry (validateWidgetType, validatePolicyScope, activeWidgetTypes, activePolicyScopes)
import Application.Helper.AgentBridge (callAgent, checkGovernancePolicy)
import Application.Helper.AgentBridge (callAgent, checkGovernancePolicy, bridgeErrorMessage)
import Application.Helper.ModelRouter (resolveAgent)
import Data.List (intercalate)
@@ -209,7 +209,7 @@ instance Controller WidgetsController where
result <- liftIO $ callAgent agent userMsg
case result of
Left err -> do
setErrorMessage ("AI summarization failed: " <> err.errorMessage)
setErrorMessage ("AI summarization failed: " <> bridgeErrorMessage err)
redirectTo ShowWidgetAction { widgetId }
Right resp -> do
newRecord @AgentProposal
@@ -258,7 +258,7 @@ instance Controller WidgetsController where
result <- liftIO $ callAgent agent userMsg
case result of
Left err -> do
setErrorMessage ("AI draft failed: " <> err.errorMessage)
setErrorMessage ("AI draft failed: " <> bridgeErrorMessage err)
redirectTo ShowWidgetAction { widgetId }
Right resp -> do
newRecord @AgentProposal