Repository navigation
Conversation
A phase with judge SERVICE and a convergence.service block (provider, model, reference-only parameters, prices, timeout) now asks that model directly through SummarizationService instead of running a moderator-agent turn. It runs without a moderator, books its spend on the ledger as system:judge:<phase>:<repeat>, and never ends a phase on a failure or an unreadable reply. SERVICE without the block keeps the moderator fallback. Save time refuses plaintext credentials and connection references in the parameters.
…e editor Judge = Service now shows provider, model, an API key reference, both prices and the timeout, and says when it falls back to the moderator. normalizeConvergence carries the service block through instead of dropping it. Strings live in a new groupServiceJudge namespace in all 11 locales; the stale 'not yet wired' note is removed.
New page group-service-judge.md, linked from SUMMARY.md and from the convergence paragraph of group-conversations.md, which no longer calls SERVICE unwired. Changelog fragment and the deferred operator/MCP follow-up note.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
Warning Review limit reachedEnable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing. Next included review available in 37 minutes. View limit details
Walkthrough
Security architecture risk:
|
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
|
@coderabbitai full review |
Action not completed
|
|
@coderabbitai full review |
Action performed
|
… empty references, call-rate unit
… all agents, checked at save and before resolving
…hema; give the argument-schema panel its own id
Summary
convergence.judge: SERVICEused to be a name only: with no model behind it the check silently fell back to the moderator agent, so a group with no moderator could never stop a repeating phase early, and a group with an expensive moderator paid a full agent turn per convergence check. This PR givesSERVICEits own model: one direct LLM call per check, no agent, no pipeline, no moderator required.What changed
Backend
ServiceJudgeConfigis a newconvergence.serviceblock (provider, model, parameters, optional per-1M prices,timeoutMs). It is the 6th component ofConvergenceConfig; the old 5-arg constructor is kept so existing code and stored configs behave as before.ServiceConvergenceJudgecallsSummarizationService.summarizeWithUsagewith a fixed system instruction (member text is declared to be material, not instructions); the judge prompt travels as the user message, as data. The timeout is forced fromtimeoutMs(capped at 60 s), overriding anytimeoutinparameters.system:judge:<phaseIndex>:<repeat>plus acost_updatedevent, so it shows inmemberCosts/totalCost. A reply that cannot be read was still paid for and is still booked.JudgeCallPricingis the single pricing seam; it usesTokenPricing.costfor now. The F1 cost-accounting work will re-point it (that PR is not open yet; this one does not depend on it).ServiceJudgeValidationruns at save time: it rejects plaintext credentials inparameters(400 naming the field, never the value), rejects${connection:...}references, and rejects a provider/model pair with only one half set. It warns onSERVICEwith no model (falls back to the moderator) and on an unknownjudgevalue.eddi.group.convergence.judge.duration, tagsjudge=service,mode,outcome; charted as panel id 320 in the Full Metrics Reference (k8s copies re-synced) and listed indocs/metrics.md.Manager: the phase editor shows the service fields (provider, model, prices, timeout) when Judge is set to Service; en plus the ten other locales.
Docs: new
docs/group-service-judge.md, adocs/group-conversations.mdpointer, adocs/SUMMARY.mdline, changelog fragment, andplanning/operator-followups/group-service-judge.md.Config surface
Off by default: nothing changes unless a phase opts into
judge: SERVICEand names a model.MODERATORstays the default judge, andSERVICEwithout a model still runs the moderator exactly as before.What this breaks
Nothing for stored configs: the new
servicefield is optional and absent on every existing document. A config saved earlier withjudge: SERVICEand no model behaves as before and now logs a warning on re-save instead of failing. No REST path, MCP tool or A2A change; the group configuration gains one optional nested object.Rolling upgrade: configs are only affected once a designer adds
convergence.service; until every node runs this version, do not add the block (a node without the field cannot honour it).Look hardest at
PhaseExecutionEngine.runJudge(the dispatch between the two judges and the budget/maxTurnsgates both share).ServiceJudgeValidation: the credential classifier and the${connection:...}refusal, since this is the one place a group configuration could become a plaintext key store.Verification
formatter:validate) clean. New unit tests:ServiceConvergenceJudgeTest,ServiceJudgeValidationTest.ImportStyleTest,BuildQualityGatesTest,ChangelogRotationTest,ChangelogFragmentTest,Documentation*Tests,DocumentedRestPathsTest,DeploymentManifestsTest,MetricsDashboardCoverageTest,DescriptorTypeConsistencyTest,ConfigurationReferenceCoverageTest.Merge order and conflicts
Independent of the sibling group PRs. Expect small textual conflicts with them in
docs/SUMMARY.md(each adds a line under Group Conversations, keep all),GroupConversationService(constructor end),PhaseExecutionEngine,AgentGroupStoreimports, the locale JSON files andgroup-phase-editor.tsx.Follow-ups
Platform Operator prompt and allow-list updates are deliberately not in this PR; they are tracked in
planning/operator-followups/group-service-judge.mdfor a combined integration PR.Summary by CodeRabbit