context: norris_tasks anchor + task-hint composition + reset clear
Phase 10 C2. Three additive changes; no regression. - compose_norris_task_hint(self) — module-scope helper. Returns "" when norris_tasks is nil OR list empty OR current pointer past end. Otherwise returns "\n\nCurrent step k/N:\n <task text>". - Context:to_messages appends the hint AFTER the NORRIS suffix, inside the existing `if self.norris_active and self.norris_goal` branch. NORRIS_SUFFIX_TEMPLATE is UNCHANGED (R2 fix); the hint is a separate concatenation. Goal anchor stays the primary per-step instruction; task hint sharpens current focus. - Context:reset() now clears self.norris_tasks (R6 fix). :reset is unreachable mid-Norris (planner runs without readline prompt), but if a Norris session crashed leaving stale state, :reset recovers cleanly. One line; defensive. 15 unit cases verified: - nil/empty/exhausted norris_tasks -> no hint block - current=1/3 -> "Current step 1/3" + task text in output - NORRIS suffix precedes hint (ordering preserved) - hint suppressed when norris_active=false even if tasks set - self.turns + self.norris_tasks table identity unmutated - Context:reset clears norris_tasks AND turns Regression: 87/87 safety, 31/31 router_model, repl loads. C2 isn't called from anywhere yet (ctx.norris_tasks is always nil until C4 wires the preplan call). No behavior change in the live tree until then. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+20
@@ -228,6 +228,20 @@ The user will be prompted to confirm destructive actions; expect their
|
||||
verdict in the next turn as a synthesized "[aish] ... skipped by user"
|
||||
message if they declined.]]
|
||||
|
||||
-- Phase 10 / #89: optional task-hint block appended AFTER the NORRIS
|
||||
-- suffix when the cloud preplanner emitted a TASK list at :norris
|
||||
-- launch. self.norris_tasks shape: { current = 1, list = {...} }.
|
||||
-- Returns "" when no tasks (preplan disabled OR preplan failed OR
|
||||
-- list exhausted) — keeps the NORRIS suffix backward-compatible.
|
||||
local function compose_norris_task_hint(self)
|
||||
if not (self.norris_tasks and self.norris_tasks.list) then return "" end
|
||||
local k = self.norris_tasks.current
|
||||
local n = #self.norris_tasks.list
|
||||
local task = self.norris_tasks.list[k]
|
||||
if not task then return "" end -- exhausted → no hint
|
||||
return string.format("\n\nCurrent step %d/%d:\n %s", k, n, task)
|
||||
end
|
||||
|
||||
-- #87: route-aware context compression. Keeps the LAST keep_turns
|
||||
-- turns; tail-truncates any turn whose content exceeds max_turn_chars.
|
||||
-- Drops tool turns at the slice head (they'd be orphaned without
|
||||
@@ -285,6 +299,7 @@ function Context:to_messages(opts)
|
||||
if self.norris_active and self.norris_goal then
|
||||
sys_content = sys_content
|
||||
.. string.format(NORRIS_SUFFIX_TEMPLATE, self.norris_goal)
|
||||
.. compose_norris_task_hint(self)
|
||||
end
|
||||
local msgs = { { role = "system", content = sys_content } }
|
||||
|
||||
@@ -517,6 +532,11 @@ function Context:reset()
|
||||
self.turns = {}
|
||||
self.pending_exec_output = nil
|
||||
self.summary = nil
|
||||
-- Phase 10 R6: clear norris_tasks defensively. :reset is
|
||||
-- unreachable mid-Norris (no readline prompt while the planner
|
||||
-- runs), but if a Norris session crashed leaving the field stale,
|
||||
-- :reset gives the user a clean recovery path.
|
||||
self.norris_tasks = nil
|
||||
-- R8 parity: usage_totals + cost_warn_state preserved (matches
|
||||
-- memory_items + project — "ambient context survives a user-
|
||||
-- driven conversation reset"). Use :reset_usage to zero the
|
||||
|
||||
Reference in New Issue
Block a user