Skip to content

Ralph/prd 141 platform reliability#389

Merged
AutomatosAI merged 7 commits into
mainfrom
ralph/prd-141-platform-reliability
May 28, 2026
Merged

Ralph/prd 141 platform reliability#389
AutomatosAI merged 7 commits into
mainfrom
ralph/prd-141-platform-reliability

Conversation

@AutomatosAI
Copy link
Copy Markdown
Owner

No description provided.

…-009)

Previously two limits failed silently: a chat agent that hit
CHATBOT_MAX_TOOL_ITERATIONS just returned its best-effort answer with no
signal, and a mission that blew past its token budget only logged a
diagnostic event. Both now surface a user-facing reason.

- streaming.py: add format_aisdk_limit_reached() — a typed limit_reached
  AI SDK data frame (limit/value/message) consistent with the other
  format_aisdk_* events and safe for the text/plain StreamingResponse.
- chatbot service _run_tool_loop: emit that frame at the max-iterations
  cap before forcing the final response, telling the user a cap was hit
  and how an admin can raise it.
- coordinator _record_task_result: enrich the existing 1.5x-overage
  BUDGET_WARNING with limit_type/spent/limit/message (kept the diagnostic
  tokens_used/ratio fields). Purely additive — no pause/flow change.
- tests: test_us009_limit_reporting.py covers the SSE frame contract and
  the coordinator emit (over/under/no-budget cases). Loads streaming.py in
  isolation so the formatter test needs no chatbot package deps.
…PRD-141 US-010)

Replace the hardcoded _POWER_MODE_CAPS dict with _get_power_mode_caps(power_mode, db),
which reads system_settings('power_modes', <mode>) and merges stored overrides over
hardcoded _POWER_MODE_DEFAULTS. Stored keys win; absent keys fall back; unknown modes
resolve to 'standard'; any DB error falls back to defaults (never raises on the mission
hot path). Caps are resolved once on the serial _prepare_task path and threaded through
the prep dict to the DB-free _run_agent_io, preserving the Phase 2 no-DB invariant.
Add ContextRouter._compute_budgets(context_window): when the model context
window is known, each section gets a fixed proportion of the usable window
(usable = 80% of raw); when unknown, fall back to the static CONTEXT_BUDGET_*
config values. Weights: session 10%, long_term 15%, temporal 10%, daily 8%,
awareness 5%, tools 20%, system_prompt 12% (sum 0.80 of usable, leaving slack).

retrieve_context now takes an optional context_window and sources its budgets
from _compute_budgets, so config is fallback-only when a window is available.
Threaded the optional param through UnifiedMemoryService.retrieve_context.
Added CONTEXT_BUDGET_TOOLS/SYSTEM_PROMPT to config to complete the fallback set.
Add _thresholds_for_model(context_window) -> (compact_threshold,
keep_recent_turns), tiered: >=200K (0.90,12), >=100K (0.85,8), >=32K (0.80,6),
>=8K (0.75,4), else (0.70,3); unknown/non-positive window falls back to the
static COMPACT_THRESHOLD / KEEP_RECENT_TURNS. check_and_compact now derives both
values from the model window and threads keep_recent_turns into _compact, so
large-context models compact later and keep more turns while small-context
models compact earlier — preventing context_length_exceeded and runaway memory.

Also fix a latent bug in _compact's tombstone: it called self.count_tokens /
self.count_message_tokens (module-level functions, not methods) and passed a
single dict where a list was expected — any real compaction would have raised
AttributeError. Now uses count_tokens(summary) / count_message_tokens(old_turns).
Add get_by_tags(tags) -> List[ActionDefinition] with OR semantics (an action
matches if it carries any requested tag); calls _ensure_initialized() first,
matching get_by_category (which already existed). Pure-additive — no behaviour
change to existing registry consumers. Unblocks US-015's registry-driven
intent->category filtering.
…PRD-141 US-014)

Delete the chatbot router's own embedding path (_ensure_embeddings,
_rank_tools_by_similarity, the 4 embedding-state attrs, and the
core.math.vector_operations / core.llm.embedding_manager imports). When
SEMANTIC_TOOL_ROUTING is on, route() now delegates to GraphRouter.rank_chains
— the single tool-selection pipeline — and filters available_tools to the
ranked chain actions, always preserving CORE_TOOLS, ALWAYS_INCLUDE, and the
classifier's suggested tools. agent_id is threaded from ContextService so
GraphRouter can scope per-agent edges/affinities. On GraphRouter failure we
emit a structured record_error(subsystem="routing") and fall back to category
filtering instead of a bare warning.
…-015)

Delete the hardcoded TOOL_CATEGORIES / INTENT_TO_TOOLS class dicts and the
dead _filter_tools_by_categories / _tool_matches_query helpers. The category
fallback now maps intent -> ActionRegistry category names via a module-level
_INTENT_TO_REGISTRY_CATEGORIES dict and pulls action names from the registry
at call time, so a new action under an already-mapped category is
auto-discoverable with no router edit. Kept set is unioned with the
classifier's suggested tools + CORE_TOOLS + ALWAYS_INCLUDE. Registry lookup is
wrapped so a registry hiccup degrades gracefully instead of crashing routing.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Warning

Review limit reached

@AutomatosAI, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 57 minutes and 52 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0332d9b7-44ab-4fad-949c-075ad58e0892

📥 Commits

Reviewing files that changed from the base of the PR and between f74d905 and 69c9b2f.

📒 Files selected for processing (17)
  • orchestrator/config.py
  • orchestrator/consumers/chatbot/service.py
  • orchestrator/consumers/chatbot/smart_tool_router.py
  • orchestrator/consumers/chatbot/streaming.py
  • orchestrator/core/context_guard.py
  • orchestrator/modules/context/sections/tools.py
  • orchestrator/modules/memory/context_router.py
  • orchestrator/modules/memory/unified_memory_service.py
  • orchestrator/modules/tools/discovery/action_registry.py
  • orchestrator/services/coordinator_service.py
  • orchestrator/tests/test_context_guard.py
  • orchestrator/tests/test_us009_limit_reporting.py
  • orchestrator/tests/test_us010_power_mode_caps.py
  • orchestrator/tests/test_us011_context_budgets.py
  • orchestrator/tests/test_us013_action_registry_lookups.py
  • orchestrator/tests/test_us014_graph_router_delegation.py
  • orchestrator/tests/test_us015_registry_intent_filter.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ralph/prd-141-platform-reliability

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@AutomatosAI AutomatosAI merged commit b964a8e into main May 28, 2026
1 of 2 checks passed
@AutomatosAI AutomatosAI deleted the ralph/prd-141-platform-reliability branch May 28, 2026 22:24
AutomatosAI pushed a commit that referenced this pull request May 29, 2026
…sion)

PR #389 (US-014/US-015) rewrote SmartToolRouter to filter available_tools
down to GraphRouter chains ∪ CORE_TOOLS ∪ ALWAYS_INCLUDE ∪ suggested. Neither
path preserved widget_open_callback_form, so on a "can someone call me back"
turn (classified multi_step) the tool was dropped. The LLM, instructed by its
skill to open the form, then improvised composio_execute(action=
"widget_open_callback_form"), which the composio executor parses as app
"WIDGET" and rejects: "'WIDGET' is not assigned to agent 541".

Pin widget_open_callback_form in ALWAYS_INCLUDE so it survives both the
GraphRouter and category-fallback paths. Safe because the tool only enters
available_tools when the Site has callback.enabled (gated upstream by
validate_tool_access); ALWAYS_INCLUDE only re-includes already-present tools.

Also refresh the stale PUBLIC_WIDGET_CONFIG_KEYS trip-wire (cart_idle +
callback were added to the whitelist in 16cbc1c but the conscious-update
assertion was never updated).
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.

2 participants