mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-09 04:40:45 +08:00
- Add runtime/plan_agent_v2 package and shims; gateway/direct_loop/WS wiring - Admin chat: interaction mode and specialist only in user menu; session API stores memory_mode and execution_mode only - POST /admin/api/chat/user-mode mirrors plan_agent_version to AIA_EXPERT_PLAN_AGENT_V2_ENABLED (v2 to 1, v1 to 0) - Composer cleanup (hidden mode select, no reasoning toggle in meta bar); tests and _local/system.env.example Co-authored-by: Cursor <cursoragent@cursor.com>
60 lines
2 KiB
Python
60 lines
2 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
import time
|
|
from typing import Any
|
|
|
|
from .models import PLAN_MODE_NORMAL, PlanAgentStateV2
|
|
|
|
|
|
def _state_key(session_id: str) -> str:
|
|
return f"AIA_PLAN_AGENT_V2_STATE:{str(session_id or '').strip()}"
|
|
|
|
|
|
class PlanAgentStateStoreV2:
|
|
def __init__(self, store: Any):
|
|
self._store = store
|
|
|
|
def load(self, *, session_id: str) -> PlanAgentStateV2:
|
|
sid = str(session_id or "").strip()
|
|
if not sid:
|
|
return PlanAgentStateV2()
|
|
raw = str(self._store.get_setting(_state_key(sid)) or "").strip()
|
|
if not raw:
|
|
return PlanAgentStateV2()
|
|
try:
|
|
obj = json.loads(raw)
|
|
except Exception:
|
|
return PlanAgentStateV2()
|
|
return PlanAgentStateV2.from_dict(obj if isinstance(obj, dict) else None)
|
|
|
|
def save(self, *, session_id: str, state: PlanAgentStateV2) -> PlanAgentStateV2:
|
|
sid = str(session_id or "").strip()
|
|
if not sid:
|
|
return state
|
|
now_ms = int(time.time() * 1000)
|
|
next_state = PlanAgentStateV2(
|
|
mode=state.mode,
|
|
owner_specialist=state.owner_specialist,
|
|
plan_id=state.plan_id,
|
|
plan_path=state.plan_path,
|
|
plan_content=state.plan_content,
|
|
plan_confirmed=bool(state.plan_confirmed),
|
|
entered_at_ms=int(state.entered_at_ms or 0),
|
|
updated_at_ms=now_ms,
|
|
last_user_text_norm=str(state.last_user_text_norm or "").strip().lower(),
|
|
plan_loop_count=int(state.plan_loop_count or 0),
|
|
)
|
|
self._store.set_setting(_state_key(sid), json.dumps(next_state.to_dict(), ensure_ascii=False))
|
|
return next_state
|
|
|
|
def reset(self, *, session_id: str) -> PlanAgentStateV2:
|
|
sid = str(session_id or "").strip()
|
|
if not sid:
|
|
return PlanAgentStateV2()
|
|
self._store.delete_setting(_state_key(sid))
|
|
return PlanAgentStateV2(mode=PLAN_MODE_NORMAL)
|
|
|
|
|
|
__all__ = ["PlanAgentStateStoreV2"]
|
|
|