From fbe0d17409482b105d6a48b93bf1ef7774f9dc0a Mon Sep 17 00:00:00 2001 From: mschoi Date: Mon, 26 Oct 2026 18:06:34 +0900 Subject: [PATCH] =?UTF-8?q?feat(agent):=20the=20agent=20identity=20is=20Au?= =?UTF-8?q?toBot=20=E2=80=94=20graph/assistant/subagent=20name=20autobot?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Renames the LangGraph identity from the historical blue_cell to the product name: graph key + assistant id + subagent name + entry-points + module (autobot.py) + prompt file/identity. The monitor's agent calls (BLUE_AGENT_URL) target assistant_id 'autobot'. No protocol changes — the LangGraph Platform HTTP API contract is identical. --- examples/local-sensor/blue_monitor.py | 6 ++--- langgraph.json | 2 +- .../agent/{blue_cell.py => autobot.py} | 24 +++++++++---------- .../prompts/{blue_cell.md => autobot.md} | 2 +- packages/autobot/pyproject.toml | 4 ++-- ..._cell_wiring.py => test_autobot_wiring.py} | 12 ++++------ .../test_prompt_injection_shield.py | 2 +- .../unit/middleware/test_untrusted_output.py | 2 +- 8 files changed, 26 insertions(+), 28 deletions(-) rename packages/autobot/autobot/agent/{blue_cell.py => autobot.py} (87%) rename packages/autobot/autobot/agent/prompts/{blue_cell.md => autobot.md} (97%) rename packages/autobot/tests/unit/agent/{test_blue_cell_wiring.py => test_autobot_wiring.py} (91%) diff --git a/examples/local-sensor/blue_monitor.py b/examples/local-sensor/blue_monitor.py index 7b1ec9b..41e07e8 100644 --- a/examples/local-sensor/blue_monitor.py +++ b/examples/local-sensor/blue_monitor.py @@ -925,7 +925,7 @@ def detect_page(events: list[dict]) -> dict[int, list[tuple[str, str, str]]]: result = post_json( f"{AGENT_URL}/runs/wait", { - "assistant_id": "blue_cell", + "assistant_id": "autobot", "input": {"messages": [{"role": "user", "content": prompt}]}, }, timeout=120, @@ -1142,7 +1142,7 @@ def review_watch_batch(events: list[dict], store: MonitorStore = STORE) -> dict: result = post_json( f"{AGENT_URL}/threads/{thread_id}/runs/wait", { - "assistant_id": "blue_cell", + "assistant_id": "autobot", "if_not_exists": "create", "input": {"messages": [{"role": "user", "content": prompt}]}, }, @@ -1241,7 +1241,7 @@ def analyze_forever() -> None: result = post_json( f"{AGENT_URL}/runs/wait", { - "assistant_id": "blue_cell", + "assistant_id": "autobot", "input": {"messages": [{"role": "user", "content": prompt}]}, }, timeout=180, diff --git a/langgraph.json b/langgraph.json index aec2b67..b8f96cb 100644 --- a/langgraph.json +++ b/langgraph.json @@ -1,7 +1,7 @@ { "dependencies": ["./packages/autobot"], "graphs": { - "blue_cell": "./packages/autobot/autobot/agent/blue_cell.py:graph" + "autobot": "./packages/autobot/autobot/agent/autobot.py:graph" }, "env": ".env", "python_version": "3.13", diff --git a/packages/autobot/autobot/agent/blue_cell.py b/packages/autobot/autobot/agent/autobot.py similarity index 87% rename from packages/autobot/autobot/agent/blue_cell.py rename to packages/autobot/autobot/agent/autobot.py index 4e19bbc..17c7094 100644 --- a/packages/autobot/autobot/agent/blue_cell.py +++ b/packages/autobot/autobot/agent/autobot.py @@ -1,6 +1,6 @@ -"""The blue_cell investigation agent — AutoBot's own graph export. +"""The AutoBot investigation agent — the graph export. -Adapted from Decepticon's ``agents/standard/blue_cell.py``: same read-only +Adapted from the Decepticon in-tree prototype: same read-only tool set and prompt, but the framework dependencies are replaced by AutoBot's own runtime — the thin LiteLLM-direct model factory (``agent.models``) and the directly-assembled middleware list (no slot registry): @@ -42,7 +42,7 @@ ) from decepticon_core.plugin_loader import SubAgentSpec -_ROLE = "blue_cell" +_ROLE = "autobot" _RECURSION_LIMIT = 120 _STANDARD_TOOLS: list[Any] = [ @@ -55,8 +55,8 @@ def load_system_prompt() -> str: - """Load the blue_cell system prompt from the packaged prompts dir.""" - resource = resources.files("autobot.agent").joinpath("prompts/blue_cell.md") + """Load the AutoBot system prompt from the packaged prompts dir.""" + resource = resources.files("autobot.agent").joinpath("prompts/autobot.md") return resource.read_text(encoding="utf-8") @@ -71,7 +71,7 @@ def default_middleware(model: Any) -> list[Any]: UntrustedOutputMiddleware(), PromptInjectionShieldMiddleware(append_policy_to_system=False), TokenBudgetMiddleware(), - # blue_cell has no sandbox: summaries land in graph state, not on + # AutoBot has no sandbox: summaries land in graph state, not on # a filesystem (the deepagents StateBackend is the in-memory one). create_summarization_middleware(model=model, backend=StateBackend()), AnthropicPromptCachingMiddleware(), @@ -79,7 +79,7 @@ def default_middleware(model: Any) -> list[Any]: ] -def create_blue_cell_agent( +def create_autobot_agent( *, model: Any = None, tools: list[Any] | None = None, @@ -109,17 +109,17 @@ def create_blue_cell_agent( ).with_config({"recursion_limit": recursion_limit or _RECURSION_LIMIT}) -# The red orchestrator dispatches blue_cell as a subagent (the purple loop): +# The red orchestrator dispatches AutoBot as a subagent (the purple loop): # discovered via the ``decepticon.subagents`` entry-point declared in this # package's metadata. parent_agents pins it to the ``decepticon`` main agent. SUBAGENT_SPEC = SubAgentSpec( - name="blue_cell", + name="autobot", description=( - "Blue Cell — independent read-only defender. Investigates live local " + "AutoBot — independent read-only defender. Investigates live local " "target telemetry and the always-on monitor's incidents, then reports " "evidence and uncertainty. No bash or containment tools." ), - factory=create_blue_cell_agent, + factory=create_autobot_agent, parent_agents=("decepticon",), bundle="standard", priority=90, @@ -132,5 +132,5 @@ def __getattr__(name: str): # ``graph`` attribute ("module:graph"); PEP 562 defers the model env # read from import time to attribute resolution time. if name == "graph": - return create_blue_cell_agent() + return create_autobot_agent() raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/packages/autobot/autobot/agent/prompts/blue_cell.md b/packages/autobot/autobot/agent/prompts/autobot.md similarity index 97% rename from packages/autobot/autobot/agent/prompts/blue_cell.md rename to packages/autobot/autobot/agent/prompts/autobot.md index 722128a..de71627 100644 --- a/packages/autobot/autobot/agent/prompts/blue_cell.md +++ b/packages/autobot/autobot/agent/prompts/autobot.md @@ -1,5 +1,5 @@ -You are Decepticon Blue Cell, an independent defensive agent. Your primary +You are AutoBot, an independent defensive agent. Your primary evidence is live telemetry from the target's local web sensor. The monitor continues to consume events and open incidents while no one is chatting with you. Investigate those incidents and explain what was observed. diff --git a/packages/autobot/pyproject.toml b/packages/autobot/pyproject.toml index 913d6d8..96c89bc 100644 --- a/packages/autobot/pyproject.toml +++ b/packages/autobot/pyproject.toml @@ -73,12 +73,12 @@ opensearch = "autobot.stores.opensearch_store:OpenSearchEventStore" # hosted by the Decepticon LangGraph server without in-tree blue code # (migration plan stage 2c; Decepticon design doc §0.5 client guarantee). [project.entry-points."decepticon.agents"] -blue_cell = "autobot.agent.blue_cell:graph" +autobot = "autobot.agent.autobot:graph" # The red orchestrator dispatches blue_cell as a subagent when this package # is installed (``decepticon[blue]``) — the purple loop's defender side. [project.entry-points."decepticon.subagents"] -blue_cell = "autobot.agent.blue_cell:SUBAGENT_SPEC" +autobot = "autobot.agent.autobot:SUBAGENT_SPEC" [project.urls] Homepage = "https://github.com/BitterSecurity/AutoBot" diff --git a/packages/autobot/tests/unit/agent/test_blue_cell_wiring.py b/packages/autobot/tests/unit/agent/test_autobot_wiring.py similarity index 91% rename from packages/autobot/tests/unit/agent/test_blue_cell_wiring.py rename to packages/autobot/tests/unit/agent/test_autobot_wiring.py index 9e7f52a..891b38e 100644 --- a/packages/autobot/tests/unit/agent/test_blue_cell_wiring.py +++ b/packages/autobot/tests/unit/agent/test_autobot_wiring.py @@ -2,9 +2,9 @@ import pytest -from autobot.agent.blue_cell import ( +from autobot.agent.autobot import ( build_model, - create_blue_cell_agent, + create_autobot_agent, default_middleware, default_tools, load_system_prompt, @@ -36,7 +36,7 @@ def test_default_tools_are_the_five_readonly_sensor_tools() -> None: def test_default_construction_yields_compiled_graph() -> None: - graph = create_blue_cell_agent() + graph = create_autobot_agent() from langgraph.graph.state import CompiledStateGraph assert isinstance(graph, CompiledStateGraph) @@ -45,7 +45,7 @@ def test_default_construction_yields_compiled_graph() -> None: def test_tool_injection_is_respected() -> None: tools = [blue_sensor_scan] - graph = create_blue_cell_agent(tools=tools) + graph = create_autobot_agent(tools=tools) assert "tools" in graph.nodes # The injected list replaces the default assembly wholesale. assert tools == [blue_sensor_scan] @@ -78,7 +78,5 @@ def test_middleware_injection_is_respected() -> None: # A foreign list replaces the default assembly wholesale (the real # middleware interface is exercised; a bare object would not survive # create_agent's construction-time introspection). - graph = create_blue_cell_agent( - middleware=[UntrustedOutputMiddleware(), TokenBudgetMiddleware()] - ) + graph = create_autobot_agent(middleware=[UntrustedOutputMiddleware(), TokenBudgetMiddleware()]) assert "tools" in graph.nodes diff --git a/packages/autobot/tests/unit/middleware/test_prompt_injection_shield.py b/packages/autobot/tests/unit/middleware/test_prompt_injection_shield.py index fb0efe7..ca00f6f 100644 --- a/packages/autobot/tests/unit/middleware/test_prompt_injection_shield.py +++ b/packages/autobot/tests/unit/middleware/test_prompt_injection_shield.py @@ -202,7 +202,7 @@ def test_skill_loader_name_resolved_from_registry(): def test_skill_registries_absent_uses_documented_fallback(): # AutoBot has no skills registries (decepticon.tools.skills / skillogy are - # not installed and blue_cell declares no SKILLS slot). The resolver's + # not installed and AutoBot declares no SKILLS slot). The resolver's # guarded imports fail and the documented fallback keeps the historical # skill-tool names trusted — AutoBot's actual steady state. _skill_tool_names.cache_clear() diff --git a/packages/autobot/tests/unit/middleware/test_untrusted_output.py b/packages/autobot/tests/unit/middleware/test_untrusted_output.py index 987dc48..cd73d3a 100644 --- a/packages/autobot/tests/unit/middleware/test_untrusted_output.py +++ b/packages/autobot/tests/unit/middleware/test_untrusted_output.py @@ -342,4 +342,4 @@ def test_missing_ledger_path_silently_skipped(self) -> None: # NOTE: Decepticon's TestSlotRegistration exercised the framework's # middleware-slot registry (DEFAULT_SLOT_FACTORIES / SLOTS_PER_ROLE). AutoBot # assembles its middleware list directly (agent-runtime design §middleware); -# the assembly wiring is tested when the blue_cell graph lands (2b-ii PRs). +# the assembly wiring is tested when the AutoBot graph lands (2b-ii PRs).