Skip to content

Exp: More standard agent strucutre - #32

Open
axelpey wants to merge 6 commits into
mainfrom
codex/better_agent
Open

Exp: More standard agent strucutre#32
axelpey wants to merge 6 commits into
mainfrom
codex/better_agent

Conversation

@axelpey

@axelpey axelpey commented Feb 17, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@axelpey
axelpey marked this pull request as draft September 6, 2026 03:00
@axelpey
axelpey marked this pull request as ready for review September 6, 2026 03:03
@greptile-apps

greptile-apps Bot commented Sep 6, 2026

Copy link
Copy Markdown

Greptile Summary

This PR standardizes user-facing “primitive” terminology to “skill,” enriches selected skills with registered guidance, introduces compact model-oriented history, adds skill-feedback images, and prioritizes completion events by cancelling current Brain processing.

  • Completion prioritization currently drops non-image work that happens to be active.
  • Parallel chat completion can corrupt the shared pending-user-message state.
  • Feedback images need bounded model inclusion and export redaction.

Confidence Score: 3/5

The PR is not safe to merge until completion handling stops dropping unrelated queued work and parallel chat tasks preserve latest-message ordering.

Completion events can cancel and permanently discard any queued operation, while out-of-order chat tasks can erase or resurrect user commands; feedback images also bypass model-context limits and persistence redaction.

Files Needing Attention: src/brain.py, src/history/history.py, src/brain_utils/primitive_handler.py

Important Files Changed

Filename Overview
src/brain.py Adds completion-driven cancellation and pending chat-message management, with blocking event-loss and out-of-order shared-state defects.
src/history/history.py Adds compact model history and feedback-image support, but feedback images bypass normal request bounds and export redaction.
src/brain_utils/primitive_handler.py Records optional skill-feedback images directly into history without count, size, format, or persistence controls.
src/agents/native_gemini_vision_agent.py Renames prompt terminology and exposes enriched running-skill guidance without an independently established defect.
src/brain_utils/chat_handler.py Uses compact model history and aligns the fast agent’s available-skill list with the slow agent.
src/debug_panel_static/script.js Renames the current-action renderer and labels from primitive to skill without changing rendering behavior.

Sequence Diagram

sequenceDiagram
    participant C as Robot client
    participant Q as Brain queue
    participant P as Current processing task
    participant B as Brain state
    participant V as Vision agent

    C->>Q: Queued reset/register/image event
    Q->>P: process_message(event)
    C->>B: PRIMITIVE_COMPLETED
    B--xP: cancel current task
    Note over P,Q: Cancelled event is not requeued
    B->>B: Process completion
    B->>V: Reprocess last image

    par Concurrent chat A
        C->>B: CHAT_IN A
        B->>B: Async processing
    and Concurrent chat B
        C->>B: CHAT_IN B
        B->>B: Store latest_user_message
    end
    B->>B: A finishes later and clears shared message
Loading

Reviews (1): Last reviewed commit: "Add name matching to primitive replaceme..." | Re-trigger Greptile

Comment thread src/brain.py
Comment on lines +208 to +213
if self._current_process_task and not self._current_process_task.done():
self.logger.info(
"[Brain] PRIMITIVE_COMPLETED received - cancelling current processing to handle immediately"
)
self._pending_primitive_completed = message
self._current_process_task.cancel()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Completion Drops Active Events

When PRIMITIVE_COMPLETED arrives, this code cancels the current processing task regardless of which message it is handling. Because every queued event uses that task and cancelled events are not requeued, a completion arriving during reset, registration, pose processing, or another lifecycle event can permanently drop the operation after partial state changes. For example, registration can update the directive and skills without sending its acknowledgement, leaving the client and Brain with inconsistent state.

Knowledge Base Used:

Comment thread src/brain.py
Comment on lines 554 to +584
@@ -499,6 +576,12 @@ async def handle_chat_in(self, message: MessageIn):
await self._send_vision_output(vision_output, vision_output_for_history)
self.history.check_and_summarize()
else:
text = message.payload.get("text", "")
if text and not text.startswith("!") and not result.fast_response_sent:
# Keep the latest user message for the next image-based slow-agent call.
self.state.latest_user_message = text
elif result.fast_response_sent:
self.state.latest_user_message = None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Chat Tasks Lose Message Order

Chat requests run as independent asynchronous tasks, but each task clears or replaces the same latest_user_message value when it finishes. If a newer deferred command stores its text before an older request completes, the older request can erase that command. An older deferred request can also finish later and restore stale text. The next image can therefore omit the latest command or process an already superseded one.

Knowledge Base Used:

Comment thread src/history/history.py
Comment on lines +644 to +664
feedback_image_indices = set(
i
for i, entry in enumerate(relevant_entries)
if entry.type == HistoryEntryType.PRIMITIVE_FEEDBACK_IMAGE
)

for d_entry in deduplicated_intermediate_entries:
source_idx = d_entry["source_index"]
original_raw_type = d_entry["original_raw_type"]
original_raw_description = d_entry["original_raw_description"]

is_selected_for_multimodal_image_role = (
(
original_raw_type == HistoryEntryType.GENERIC_IMAGE
or original_raw_type == HistoryEntryType.IMAGE_PRE_ACTION
)
and source_idx in selected_image_source_indices
) or (
original_raw_type == HistoryEntryType.PRIMITIVE_FEEDBACK_IMAGE
and source_idx in feedback_image_indices
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Feedback Images Bypass Limits

This selection explicitly includes every feedback image in the 500-entry history window, while generic and pre-action images use configured recent-image limits. Since skills may send repeated feedback and ingestion has no count or size limit, later Gemini requests can contain hundreds of image parts. This can displace useful history, increase cost and latency, or cause provider request failures. Feedback images should use an appropriate bounded selection policy too.

Knowledge Base Used: Conversation history and summarization

Comment on lines +162 to +167
if image_b64:
self.logger.info(f"Received feedback image from '{task_name}'")
self.history.add(
HistoryEntryType.PRIMITIVE_FEEDBACK_IMAGE,
description=image_b64,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Feedback Images Persist Unredacted

This stores the complete base64 feedback image as the history description, but History.save() only redacts generic and pre-action image entries. The next history save therefore writes feedback image bytes directly into the JSON export, unlike existing image types. This can persist sensitive image content and substantially enlarge history files. The new feedback-image type should be covered by the export redaction logic.

Knowledge Base Used: Conversation history and summarization

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant