Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 61 additions & 32 deletions openzero/brain/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4911,6 +4911,33 @@ def voice_transcribe():
return jsonify(result)


def deterministic_browser_inspection_reply(state: Dict[str, object]) -> str:
"""Return the initial read-only browser action without spending a model call."""

skill_ids = {str(item) for item in state.get("skill_ids") or [] if str(item).strip()}
objective = str(state.get("objective") or "")
if "browser-tabs" not in skill_ids or requires_tab_pilot_evidence(objective):
return ""
target_url = objective_browser_target(objective)
if not target_url:
return ""
evidence = dict(state.get("completion_evidence") or {})
if (
evidence.get("browser_source") == "moltbot"
and evidence.get("browser_snapshot_id")
and browser_target_matches(
target_url, str(evidence.get("browser_requested_url") or "")
)
):
return ""
latest = str(state.get("current_prompt") or "")
if any(
marker in latest
for marker in ("**[MOLTBOT OFFLINE]**", "**[MOLTBOT FAILED]**", "**[MOLTBOT BUSY]**")
):
return ""
return f'<tool>{{"action":"moltbot_browse","url":{json.dumps(target_url)}}}</tool>'

def autonomous_step_prompt(state: Dict[str, object]) -> str:
"""Keep the true objective in every model turn without fabricating chat."""

Expand All @@ -4927,25 +4954,13 @@ def autonomous_step_prompt(state: Dict[str, object]) -> str:
except CatalogError as error:
skill_context = f"Skill catalog unavailable: {error}. Do not propose another operator tool."
browser_directive = ""
completion_evidence = dict(state.get("completion_evidence") or {})
objective_text = str(state.get("objective") or "")
target_url = objective_browser_target(objective_text)
explicit_tab_pilot = requires_tab_pilot_evidence(objective_text)
inspection_ready = bool(
completion_evidence.get("browser_source") == "moltbot"
and completion_evidence.get("browser_snapshot_id")
and target_url
and browser_target_matches(
target_url, str(completion_evidence.get("browser_requested_url") or "")
browser_tool_reply = deterministic_browser_inspection_reply(state)
if browser_tool_reply:
browser_directive = (
"\n\nBROWSER PROOF REQUIRED FOR THIS TURN:\n"
"Return exactly this one tool tag with no prose:\n"
f"{browser_tool_reply}"
)
)
if "browser-tabs" in skill_ids and not explicit_tab_pilot and not inspection_ready:
if target_url:
browser_directive = (
"\n\nBROWSER PROOF REQUIRED FOR THIS TURN:\n"
"Return exactly this one tool tag with no prose:\n"
f'<tool>{{"action":"moltbot_browse","url":{json.dumps(target_url)}}}</tool>'
)
return (
"[AUTONOMOUS RUN CHECKPOINT]\n"
f"Run id: {state.get('id')}\n"
Expand Down Expand Up @@ -5071,20 +5086,34 @@ def execute_autonomous_run(
break

state = AUTONOMOUS_RUN_STORE.get(run_id)
step_prompt = autonomous_step_prompt(state)
AUTONOMOUS_RUN_STORE.append_trace(
run_id,
"model_request",
step=int((state.get("usage") or {}).get("steps") or 0) + 1,
prompt=step_prompt,
)
model_agent_mode = agent_mode if state.get("skill_ids") else "conversation"
reply = autonomous_model_reply(step_prompt, comp_mode, model_agent_mode, history, upload_context)
state = AUTONOMOUS_RUN_STORE.checkpoint(
run_id,
usage_delta={"steps": 1, "model_calls": 1},
)
AUTONOMOUS_RUN_STORE.append_trace(run_id, "model_reply", reply=reply)
deterministic_reply = deterministic_browser_inspection_reply(state)
if deterministic_reply:
reply = deterministic_reply
AUTONOMOUS_RUN_STORE.append_trace(
run_id,
"deterministic_tool_proposal",
tool="moltbot_browse",
reason="explicit_url_inspection",
)
state = AUTONOMOUS_RUN_STORE.checkpoint(
run_id,
usage_delta={"steps": 1},
)
else:
step_prompt = autonomous_step_prompt(state)
AUTONOMOUS_RUN_STORE.append_trace(
run_id,
"model_request",
step=int((state.get("usage") or {}).get("steps") or 0) + 1,
prompt=step_prompt,
)
model_agent_mode = agent_mode if state.get("skill_ids") else "conversation"
reply = autonomous_model_reply(step_prompt, comp_mode, model_agent_mode, history, upload_context)
state = AUTONOMOUS_RUN_STORE.checkpoint(
run_id,
usage_delta={"steps": 1, "model_calls": 1},
)
AUTONOMOUS_RUN_STORE.append_trace(run_id, "model_reply", reply=reply)

post_allowed, post_reason = AUTONOMOUS_RUN_STORE.budget_guard(run_id)
if not post_allowed and post_reason in {"revoked", "stop_requested"}:
Expand Down
3 changes: 3 additions & 0 deletions openzero/tests/test_autonomous_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,9 @@ def test_every_continuation_prompt_names_the_original_objective(self):
self.assertIn("`text_generation` is not a tool.", self.source)
self.assertIn("Never repeat or expose this checkpoint.", self.source)
self.assertIn("BROWSER PROOF REQUIRED FOR THIS TURN", self.source)
self.assertIn("def deterministic_browser_inspection_reply(", self.source)
self.assertIn('"deterministic_tool_proposal"', self.source)
self.assertIn('usage_delta={"steps": 1}', self.source)
self.assertIn('"action":"moltbot_browse"', self.source)

def test_plain_conversation_and_model_format_recovery_are_guarded(self):
Expand Down
Loading