Conversation
在关键词自动回复写入历史时增加系统前缀标记,并仅在群聊且开关开启时向模型注入机制说明。这样可让 AI 正确识别该类消息来自系统彩蛋而非其主动决策。
在工具注册阶段按调用方过滤 call_*,实现看不见就不能点并保留执行期权限校验;同时修复 web_agent callable 配置中的 naga_code_analysis_agent 拼写。
统一要求完整 Cookie,B站下载/搜索/用户信息改为官方接口并在失败时自动补签 WBI。补充用户信息的可选字段参数,提升风控场景下的稳定性与可观测性。
在 AgentToolRegistry 中复用 callable.json 机制,让 skills/tools 下的工具可按 allowed_callers 暴露给子 Agent,且默认不声明时仍仅主 AI 可见并保持本地同名工具优先。将 get_current_time 迁移为共享主工具并移除各 Agent 重复实现,同时补充相关文档以降低维护成本。
Provide async-safe temp-cache uploads with target inference and a configurable 512KB default limit, and steer multi-file tasks to code_delivery_agent to reduce runtime overhead.
Track in-progress tasks per chat and inject them into prompt context to avoid duplicate tool/agent execution during concurrent message gaps.
Move inflight summary and title-generation prompts into res/prompts with file-based loading and safe fallbacks to simplify maintenance.
Validate externalized prompt template placeholders at runtime and add detailed debug logs for inflight summary lifecycle and prompt injection decisions.
Prioritize in-flight task context and enforce a strict triage matrix so follow-up nudges do not retrigger duplicate business tool execution.
Create per-chat inflight placeholder before the initial LLM request for @/private triggers to close the concurrent gap that caused duplicate task execution.
Add features.inflight_summary_enabled (default true) to toggle inflight placeholder injection and async summary generation for anti-duplicate handling.
Improve /stats robustness with safer prompt rendering, richer call-type/model summary dimensions, bounded time-range parsing, and clearer timeout/fallback analysis messaging.
Add README guidance for inflight summary controls, observability keywords, and /stats range+timeout behavior, plus config docs for inflight summary toggles.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
src/Undefined/ai/client.py
Outdated
There was a problem hiding this comment.
🟡 Fire-and-forget asyncio.create_task drops task reference, risking silent exception loss
At src/Undefined/ai/client.py:995, asyncio.create_task(self._enqueue_inflight_summary_generation(...)) is called without storing the returned task reference. Python's official documentation warns: "Save a reference to the result of this function, to avoid a task disappearing mid-execution."
Detailed Explanation
While CPython's event loop internally keeps references to scheduled tasks (preventing GC during execution), any unhandled exception from the task will only produce a warning log rather than being properly tracked. The project itself follows a reference-storing pattern elsewhere — for example, self._mcp_init_task = asyncio.create_task(init_mcp_async()) at src/Undefined/ai/client.py:232 and the self._track_inflight_task(inflight_task) pattern in src/Undefined/services/queue_manager.py:407.
The practical impact is mitigated because _enqueue_inflight_summary_generation has its own internal try/except handling, so exceptions won't propagate. However, if the coroutine fails before reaching that handler (e.g., due to a synchronous error in argument preparation), the exception would be silently swallowed with only a "Task exception was never retrieved" warning.
Prompt for agents
In src/Undefined/ai/client.py around line 995, store the task reference returned by asyncio.create_task and track it, similar to how _mcp_init_task is stored at line 232 or how _track_inflight_task is used in queue_manager.py. For example, add the task to a set of background tasks on the AIClient instance and use add_done_callback to remove completed tasks and log any exceptions.
Was this helpful? React with 👍 or 👎 to provide feedback.
Replace threading.Lock with asyncio.Lock to prevent event loop blocking in async environment. Add performance metrics and optimize GC triggering. Changes: - Replace threading.Lock with asyncio.Lock in InflightTaskStore - Convert all methods to async (upsert_pending, mark_ready, clear_*, list_for_chat) - Update all call sites to use await - Optimize GC: trigger by interval (60s) or threshold (100 entries) instead of every operation - Add performance metrics: total_upserts, total_mark_ready, total_clears, total_queries, total_gc_runs, total_expired_cleaned, anti_duplicate_hits, current_entries - Improve logging: upgrade key operations to info level, truncate request_id display - Add comprehensive unit tests (23 test cases covering basic ops, concurrency, TTL/GC, metrics, edge cases) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- wbi.py: add length check to prevent IndexError when WBI keys are too short - client.py: add exception handler to fire-and-forget inflight summary task Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…witches - 将进行中摘要功能拆分为两个独立开关: - inflight_pre_register_enabled(预注册占位,默认启用) - inflight_summary_enabled(摘要生成,默认禁用) - 重构 Bilibili WBI 请求逻辑: - 提取公共函数到 wbi_request.py - 优化视频信息获取流程,减少重复请求 - 修复 WBI 缓存时间戳更新 bug - 更新相关文档和配置示例 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
| updated = self.ai.set_inflight_summary_generation_result( | ||
| request_id, | ||
| action_summary, | ||
| ) |
There was a problem hiding this comment.
🔴 Missing await on async set_inflight_summary_generation_result call
In _execute_inflight_summary_generation, the call to self.ai.set_inflight_summary_generation_result(...) at line 723 is missing await. This method is declared async def at src/Undefined/ai/client.py:585 and internally awaits self._inflight_task_store.mark_ready(...). Without await, the coroutine is never executed, so the inflight task store is never updated with the generated summary.
Root Cause and Impact
Because set_inflight_summary_generation_result is async, calling it without await returns a coroutine object instead of a bool. A coroutine object is always truthy, so if updated: on line 727 always evaluates to True, and the log message "更新完成" is emitted even though no update occurred.
The actual mark_ready call inside the store never runs, meaning inflight task records are never promoted from pending to ready status. The summary text generated by the model is silently discarded. Users will only ever see the pending display text ("正在处理消息…") and never the enriched ready text ("正在处理消息…(动作摘要)"), defeating the purpose of the summary generation feature.
Additionally, the unawaited coroutine will trigger a RuntimeWarning: coroutine ... was never awaited at garbage collection time.
| updated = self.ai.set_inflight_summary_generation_result( | |
| request_id, | |
| action_summary, | |
| ) | |
| updated = await self.ai.set_inflight_summary_generation_result( | |
| request_id, | |
| action_summary, | |
| ) |
Was this helpful? React with 👍 or 👎 to provide feedback.
| should_pre_register = ( | ||
| inflight_summary_enabled | ||
| and self._should_pre_register_inflight(pre_context, question) | ||
| ) |
There was a problem hiding this comment.
🔴 Pre-registration is gated on inflight_summary_enabled, contradicting documented independent control
The should_pre_register flag at line 796-798 requires inflight_summary_enabled to be True before pre-registration can occur. Since inflight_summary_enabled defaults to False, the pre-registration feature (inflight_pre_register_enabled, default True) is effectively dead out-of-the-box.
Detailed Explanation
The code at src/Undefined/ai/client.py:796-798:
should_pre_register = (
inflight_summary_enabled
and self._should_pre_register_inflight(pre_context, question)
)This means both inflight_summary_enabled AND inflight_pre_register_enabled must be true for pre-registration to work. But the documentation (README.md line 82, config.toml.example lines 269-283, and the PR description) explicitly states these two switches are "独立控制" (independently controlled):
inflight_pre_register_enabled(defaulttrue) — pre-register placeholderinflight_summary_enabled(defaultfalse) — generate action summary
With the default config (inflight_summary_enabled=false, inflight_pre_register_enabled=true), users expect pre-registration to work but it silently does nothing. The anti-duplicate-execution feature, which is the primary goal of this PR, is non-functional unless users also enable inflight_summary_enabled.
The fix should check inflight_pre_register_enabled independently for pre-registration, and only gate summary generation on inflight_summary_enabled.
| should_pre_register = ( | |
| inflight_summary_enabled | |
| and self._should_pre_register_inflight(pre_context, question) | |
| ) | |
| should_pre_register = self._should_pre_register_inflight( | |
| pre_context, question | |
| ) |
Was this helpful? React with 👍 or 👎 to provide feedback.
核心功能
并发防重复执行(进行中摘要)
@机器人场景在首轮前预占位,并在后续请求注入"进行中的任务"上下文features.inflight_summary_enabled一键开关models.inflight_summary模型配置统计功能增强
工具改进
配置与提示词
文档更新
其他改进