Roles, capability profiles and help on the new loop (M2.6)
- roles.driver (unset: the planner's model) and roles.classifier (unset: the expert's); the mapping is pinned when an item opens, and the driver and the go-ahead reader run on the item's own (L9). - profiles: in configuration (tools, strengths, weaknesses), used in briefings: the driver's instructions say what its helper and expert are good at, the helper's brief who reads its handback; never a model name. - delegate(task) and ask_expert(question) for the driver. A helper works on a branch off the milestone's; on a handback its work comes back as uncommitted changes, otherwise it is discarded, so harness branches never hold commits only the clone has. ask_expert keeps its budget. - Triggers: failure_limit failed commands in a row (Driver's new "stuck" outcome) or the turn cap, mid-milestone, call a helper in once per milestone; if it fails too, the item waits on the operator. A delegation cut off by a crash is discarded at boot. - Evaluation capture: delegations and ask_expert as before, and the reader's verdicts as classifier pairs. Tests: help tests (merge-back, discard, needs a milestone, the stuck trigger and its once-per-milestone limit, the expert and its budget, pinning, briefings by profile, boot discarding a cut-off delegation), config tests for roles and profiles, and the walk delegating with a scripted helper that sometimes fails, with a delegations_settle property. The walk found helper commits stranded on a merged PR's branch, fixed by returning a helper's work uncommitted. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
This commit is contained in:
1 parent
04c352b30c
commit
59fd00ce8c
19 files changed
+890
-38
No files matched your search
@@ -15,11 +15,14 @@ from nisse_dev.agent import (
|
||||
remote_url,
|
||||
)
|
||||
from nisse_dev.cancel import Cancel
|
||||
from nisse_dev.catalog import select_client
|
||||
from nisse_dev.config import AgentConfig, ConfigError
|
||||
from nisse_dev.config import Project as ProjectEntry
|
||||
from nisse_dev.delegation import Caps
|
||||
from nisse_dev.gitea import GiteaClient
|
||||
from nisse_dev.loop.agent import LoopAgent, Project
|
||||
from nisse_dev.loop.driver import Driver
|
||||
from nisse_dev.loop.help import Helpers
|
||||
from nisse_dev.loop.milestones import Milestones
|
||||
from nisse_dev.loop.reader import GoAheadReader
|
||||
from nisse_dev.matrix import MatrixTransport
|
||||
@@ -124,14 +127,28 @@ def build_loop_agent(
|
||||
project_runtime(config, entry, store, gitea, account)
|
||||
for entry in config.projects
|
||||
]
|
||||
normalized, _passthrough = make_llm_clients(config, catalog)
|
||||
normalized, passthrough = make_llm_clients(config, catalog)
|
||||
cancel = Cancel()
|
||||
# The driver is the planner's model for now (M2.6 brings the driver role).
|
||||
# The configured driver; each work item runs on the one it pinned (L9).
|
||||
driver = Driver(
|
||||
normalized,
|
||||
config.roles.resolve("planner"),
|
||||
config.roles.resolve("driver"),
|
||||
max_turns=config.tuning.executor.max_turns,
|
||||
cancel=cancel,
|
||||
failure_limit=config.tuning.executor.failure_limit,
|
||||
)
|
||||
tuning = config.tuning
|
||||
helpers = Helpers(
|
||||
client=normalized,
|
||||
roles=config.roles,
|
||||
client_for=lambda model: select_client(model, normalized, passthrough, catalog),
|
||||
caps=Caps(
|
||||
turns=tuning.delegation.max_turns,
|
||||
tokens=tuning.delegation.max_tokens,
|
||||
wall_clock_s=tuning.delegation.wall_clock_s,
|
||||
),
|
||||
expert_budget=tuning.expert.consult_budget,
|
||||
profiles=config.profiles,
|
||||
)
|
||||
transport = MatrixTransport(config.matrix)
|
||||
loop = LoopAgent(
|
||||
@@ -147,9 +164,9 @@ def build_loop_agent(
|
||||
cancel=cancel,
|
||||
oplog=oplog,
|
||||
roles=config.roles.pinned(),
|
||||
# The driver's model reads plain-language go-aheads until the
|
||||
# classifier role arrives (M2.6).
|
||||
reader=GoAheadReader(normalized, config.roles.resolve("planner")),
|
||||
# The classifier role reads plain-language go-aheads (L5, L9).
|
||||
reader=GoAheadReader(normalized, config.roles.resolve("classifier")),
|
||||
helpers=helpers,
|
||||
reload=lambda known: [
|
||||
project_runtime(config, entry, store, gitea, account)
|
||||
for entry in (load or _from_file(config))().projects
|
||||
|
||||
Reference in new issue
Block a user