CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m22s
Development Plan M0.1. Every section reference in code, tests, specs/, the example config, the tuning guide, and the CLAUDE.md and README files now cites docs/Architecture.md (P, L, D, O, X, Q) instead of the old spec's A-H, and docs/Architecture-Build-Spec.md is deleted (git keeps it). The plan's old-to-new table goes with it. Mostly mechanical, with a per-site choice where one old section split: A4 became L2 where it meant stop/abandon/the loop and L3 where it meant approvals; A10 became L6 in the context-budget code and L7 elsewhere; B2 became D4 for outbound Gitea and publishing and D5 for review intake; 'A3 step N' became the matching step of L8's boot sequence. Comments describing behaviour the architecture drops (planning always escalating, thresholds tuned at an old build step) now describe the current code and point at the Development Plan. docs/Architecture.md gains one line the rewrite missed: intake outages delay but never fail work (old B2), now in L5, where the poller and Matrix code cite it. Comments and docs only; no behaviour change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
"""Live planning turn: a real model must answer with a submit_plan or
|
|
ask_human tool call, not prose.
|
|
|
|
Plans with the test config's planner role. The planner role is a frontier
|
|
model today (Development Plan §2), and small local models do not hold the tool-call
|
|
contract reliably, so that role must be one that does.
|
|
"""
|
|
|
|
import io
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from nisse_dev.canonical import UserMessage
|
|
from nisse_dev.control import AskHuman, SubmitPlan
|
|
from nisse_dev.llm import LiteLLMClient, RoleMap
|
|
from nisse_dev.oplog import OpLog
|
|
from nisse_dev.planner import LLMPlanningAgent
|
|
from nisse_dev.state import StateStore
|
|
|
|
pytestmark = pytest.mark.integration
|
|
|
|
|
|
def test_live_planning_turn_returns_a_tool_action(
|
|
tmp_path: Path, litellm: LiteLLMClient, live_model: str
|
|
) -> None:
|
|
model = live_model
|
|
roles = RoleMap(executor=model, planner=model, delegate=model, consultant=model)
|
|
store = StateStore(tmp_path / "state.db", oplog=OpLog("nisse-dev", io.StringIO()))
|
|
store.append_event(
|
|
UserMessage(
|
|
text=(
|
|
"Project 'hello-cli': a Python script that prints a greeting. "
|
|
"Draft the architecture plan."
|
|
),
|
|
source="live-test",
|
|
)
|
|
)
|
|
agent = LLMPlanningAgent(litellm, store, roles)
|
|
|
|
action = agent.plan("arch", "hello-cli")
|
|
|
|
assert isinstance(action, SubmitPlan | AskHuman)
|
|
text = action.content if isinstance(action, SubmitPlan) else action.question
|
|
assert text.strip(), "tool call carried empty content"
|
|
# The turn must be durable regardless of what the model said (L8/L7).
|
|
assert len(store.read_events()) > 1
|