Ralph/prd 141 platform reliability#389
Conversation
…-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.
|
Warning Review limit reached
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 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 configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (17)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
…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).
No description provided.