refactor(agent): gate sustained goals behind explicit /goal
Replace the legacy long-goal skill contract with command-scoped goal tools and runtime guidance. Keep goal state durable across continuations while restricting create and replace mutations to explicit user /goal turns.
This commit is contained in:
@@ -4,7 +4,9 @@ from __future__ import annotations
|
||||
|
||||
from nanobot.session.goal_state import (
|
||||
GOAL_STATE_KEY,
|
||||
MAX_GOAL_OBJECTIVE_CHARS,
|
||||
discard_legacy_goal_state_key,
|
||||
explicit_goal_requested,
|
||||
goal_state_runtime_lines,
|
||||
goal_state_ws_blob,
|
||||
parse_goal_state,
|
||||
@@ -40,6 +42,16 @@ def test_runtime_lines_include_objective_when_active():
|
||||
assert any("Summary: fix" in ln for ln in lines)
|
||||
|
||||
|
||||
def test_runtime_lines_preserve_maximum_accepted_objective():
|
||||
objective = "x" * MAX_GOAL_OBJECTIVE_CHARS
|
||||
|
||||
lines = goal_state_runtime_lines(
|
||||
{GOAL_STATE_KEY: {"status": "active", "objective": objective}}
|
||||
)
|
||||
|
||||
assert lines == ["Goal (active):", objective]
|
||||
|
||||
|
||||
def test_runtime_lines_read_legacy_thread_goal_key():
|
||||
meta = {"thread_goal": {"status": "active", "objective": "Legacy key.", "ui_summary": "L"}}
|
||||
lines = goal_state_runtime_lines(meta)
|
||||
@@ -109,6 +121,12 @@ def test_sustained_goal_active_respects_legacy_thread_goal_key():
|
||||
assert sustained_goal_active(meta) is True
|
||||
|
||||
|
||||
def test_explicit_goal_requested_only_reads_command_metadata():
|
||||
assert explicit_goal_requested({}) is False
|
||||
message_meta = {"original_command": "/goal", "goal_requested": True}
|
||||
assert explicit_goal_requested(message_meta) is True
|
||||
|
||||
|
||||
def test_runner_wall_llm_timeout_uses_metadata_override(tmp_path):
|
||||
sm = SessionManager(tmp_path)
|
||||
assert (
|
||||
|
||||
@@ -8,7 +8,11 @@ from types import SimpleNamespace
|
||||
import pytest
|
||||
|
||||
from nanobot.bus.events import InboundMessage
|
||||
from nanobot.session.goal_state import GOAL_STATE_KEY
|
||||
from nanobot.session.goal_state import (
|
||||
GOAL_STATE_KEY,
|
||||
explicit_goal_requested,
|
||||
sustained_goal_turn,
|
||||
)
|
||||
from nanobot.session.turn_continuation import (
|
||||
INTERNAL_CONTINUATION_KIND_META,
|
||||
INTERNAL_CONTINUATION_META,
|
||||
@@ -50,6 +54,8 @@ async def test_maybe_continue_turn_queues_internal_message():
|
||||
"origin_message_id": "msg-0",
|
||||
"_wants_stream": True,
|
||||
"webui": True,
|
||||
"original_command": "/goal",
|
||||
"goal_requested": True,
|
||||
},
|
||||
),
|
||||
session_key="feishu:c1",
|
||||
@@ -74,6 +80,8 @@ async def test_maybe_continue_turn_queues_internal_message():
|
||||
assert queued.metadata["message_id"] == "msg-1"
|
||||
assert queued.metadata["origin_message_id"] == "msg-0"
|
||||
assert queued.metadata["_wants_stream"] is True
|
||||
assert not explicit_goal_requested(queued.metadata)
|
||||
assert sustained_goal_turn(meta, message_metadata=queued.metadata)
|
||||
assert "Finish the migration." in queued.content
|
||||
assert ctx.all_messages == messages[:-1]
|
||||
assert ctx.final_content == ""
|
||||
|
||||
Reference in New Issue
Block a user