From 3b857a35e7d8c0cb5aacc7522283aedf5bd12f81 Mon Sep 17 00:00:00 2001 From: zccyman Date: Fri, 15 May 2026 08:15:31 +0800 Subject: [PATCH] fix(caching): include Kimi/Moonshot in OpenRouter prompt cache policy (#25970) --- .dev-workflow/code-graph.db | Bin 0 -> 65536 bytes .dev-workflow/phase-tracker.json | 74 +++++ agent/agent_runtime_helpers.py | 9 +- analyzed_issues.json | 117 ++++++++ scripts/phase_tracker.py | 445 +++++++++++++++++++++++++++++++ scripts/phase_watchdog.sh | 76 ++++++ tests/test_kimi_prefix_cache.py | 74 +++++ 7 files changed, 794 insertions(+), 1 deletion(-) create mode 100644 .dev-workflow/code-graph.db create mode 100644 .dev-workflow/phase-tracker.json create mode 100644 analyzed_issues.json create mode 100644 scripts/phase_tracker.py create mode 100755 scripts/phase_watchdog.sh create mode 100644 tests/test_kimi_prefix_cache.py diff --git a/.dev-workflow/code-graph.db b/.dev-workflow/code-graph.db new file mode 100644 index 0000000000000000000000000000000000000000..0b41e84bf29906a9c6616c456635308a155c7900 GIT binary patch literal 65536 zcmeI*!Ef4D9KdlKQW8jrGij1<-9yoqAZ1x-nvoo)Eo)eX#^{z%wVhO1Zg@?s5MW@o zOw}f(sx)c;)1>_aQ|~+Ww$rrRjymfvU*^5WOuysZ>qG5n&4jl8>$_RwU(J|%q-B3M{>b*S z?=Sqh@bmmT3kR9sGEU}p`f2*Fxku>_rlnvz0tg_000IbH6M^%};;gy6tiQBe`&mOi zcN)?d2fEaovDa^+-Do zUBi3JWZ6BprTW&;o?C^X&eC~$Vb;v$^z)}m;izM`kF8Vb+F>g@Vi0bhKyV^|yu#qW zw;MgF;zozCnN6AZbJK?v);k z(E#zFDpb&_AD-XOq|6UZJs=AsUAuE6y$SG=%}+@dgoNpWzU6p1(-U)cTfNSqR5>$K zat0w`&YGE-{Pgh?7Cx~%X9qqr>4*Sjp{2k9IgUsUj3 z>5JWmm6|B5Z;Y3FyVGjRj_b&7kg^}V^5UnJ@#vwWOsoz@wk8Jqz9!V%j#gTJE@ggV zPOCHpXBE_4`rA~>ESUO>L47q_b+5kK_L1z^%@fs|9h<_@Ab%3omeu~l#9ry(UcP)Q zQoF&!n)azwt<;pfen6Ph@8zpADwQhxGrx9&RQ{o^TDPX8@&m$D>dfGu!t&+h#9j0A zt9&z4@~Ki73|G;=%IKL-|LkL2iKrl)$2|_a$~))HLe?dl^R4xj=aR%jyzQZRzck*z4sAw{(Fh6e>1$w z_xoHBKmY**5I_I{1Q0*~0R#|0AXWkye>ANBV>PD?1_1;RKmY**5I_I{1Q0*~fv5oM z|ELIk1Q0*~0R#|0009ILKmY**;wQlRKYnw{h!8*k0R#|0009ILKmY**5Qqw}{*Q{# zM*sl?5I_I{1Q0*~0R#|0AbtX@|Km5Oj0gb)5I_I{1Q0*~0R#|00D-6g-~S&Kp^pFp z2q1s}0tg_000IagfI$2N`20V9bIOPiKmY**5I_I{1Q0*~0R#|;3b6iZpU0R#|0009ILKmY**5I_Kdr~vE#s0e)o5I_I{1Q0*~ z0R#|0009KzC*XhoU&45;8?TMO<2O1+ga85vAb)qn^;!-kaG+T9P9kzN+ zcVox@{6As5(Tq37Ki5%&eMSHQ1Q0*~0R#|0009ILK;WhdEGBb$_&b2np5b@HUjQue z|Nm}kl`w7u5I_I{1Q0*~0R#|00D+q%z~BGhq}gVy2q1s}0tg_000IagfB*tFRp38c CSYNaN literal 0 HcmV?d00001 diff --git a/.dev-workflow/phase-tracker.json b/.dev-workflow/phase-tracker.json new file mode 100644 index 00000000000..7737c819a16 --- /dev/null +++ b/.dev-workflow/phase-tracker.json @@ -0,0 +1,74 @@ +{ + "template": "github-issue", + "current_phase": 13, + "completed_phases": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13 + ], + "issue_number": 27653, + "started_at": "2026-05-18T07:02:16.341710", + "last_advanced_at": "2026-05-18T07:15:27.942283", + "state": "completed", + "phase_evidence": { + "1": { + "evidence": "Issue #27653 scored 6/7, no competing PRs found across 5 keyword searches (history, history search, prompt reuse, slash command gateway), no duplicate markers, 0 comments. Feature request: add /history cmd with search & reuse for gateway platforms. Author: zccyman. Labels: type/feature, comp/gateway.", + "timestamp": "2026-05-18T07:02:41.657629" + }, + "2": { + "evidence": "branch feat/history-gateway-27653 created from origin/main (4c46c35ed), git email set to 16263913+zccyman@users.noreply.github.com for CI attribution", + "timestamp": "2026-05-18T07:03:04.882165" + }, + "3": { + "evidence": "Code understanding complete: 6 key files analyzed. /history is cli_only=True in commands.py L74. Gateway dispatch at run.py L6505-6760 uses canonical command chain. Session store has load_transcript() and search_messages() (FTS5). Feishu cards at feishu.py L1854 support interactive buttons with value callbacks. /retry at L9690 shows transcript reading pattern.", + "timestamp": "2026-05-18T07:04:41.647803" + }, + "4": { + "evidence": "dwf_security_scan quick: all findings pre-existing in CI configs (no github, docker) and test fixtures. Feature adds read-only /history slash command that reads session store — no new code execution, no file writes, no credentials exposed. Zero risk.", + "timestamp": "2026-05-18T07:04:58.163837" + }, + "5": { + "evidence": "Modified 2 files: hermes_cli/commands.py (removed cli_only=True, added args_hint=[keyword]) and gateway/run.py (added dispatch line for history + _handle_history_command handler (96 lines). Handler supports /history, /history , /history , paginated 5/page. Syntax check passed.", + "timestamp": "2026-05-18T07:11:15.389855" + }, + "6": { + "evidence": "10 new tests in tests/gateway/test_history_command.py all PASSED (test_no_history, test_shows_recent_prompts_page_1, test_pagination_page_2, test_search_by_keyword, test_search_no_match, test_page_out_of_range_clamps_to_last_page, test_session_store_unavailable, test_filters_tool_and_assistant, test_empty_args_from_event, test_history_next_prev_navigation). Existing gateway tests (14) also PASSED — zero regressions.", + "timestamp": "2026-05-18T07:13:38.921925" + }, + "7": { + "evidence": "dwf_review_run: 0 ERROR, 1 WARNING (pre-existing http://127.0.0.1 in commands.py L1107, NOT our change), 89 INFO (all pre-existing style/assert issues). Zero new findings across 3 files reviewed.", + "timestamp": "2026-05-18T07:13:58.765627" + }, + "8": { + "evidence": "PR readiness 7/7: (1) attribution OK, (2) no new competitors, (3) diff +281/-2, (4) syntax OK, (5) 10 tests passed, (6) code review clean, (7) PR body drafted. Ready for PR creation.", + "timestamp": "2026-05-18T07:14:40.080604" + }, + "9": { + "evidence": "Phase 10: Self-evolution completed - extracted 5 decisions, 5 pitfalls, knowledge graph updated. Phase 11: No upstream gap discoveries - this PR implements an issue we filed. Phase 12: Plugin self-improvement - dev-workflow plugin performed well, phase_tracker.py correctly blocked pre-push until Phase 9.", + "timestamp": "2026-05-18T07:15:20.667105" + }, + "10": { + "evidence": "Phase 11: No upstream gap discoveries found. This PR directly implements the feature requested in the issue that we filed.", + "timestamp": "2026-05-18T07:15:23.003379" + }, + "11": { + "evidence": "Phase 12: dev-workflow plugin performed well this cycle. phase_tracker.py pre-push hook correctly blocked Phase 8 push. Only minor issue: advancing multiple phases at once is not supported — must advance one at a time.", + "timestamp": "2026-05-18T07:15:25.464885" + }, + "12": { + "evidence": "Phase 13: Cleanup complete. Branch feat/history-gateway-27653 pushed to fork. PR #27655 created at https://github.com/NousResearch/hermes-agent/pull/27655. Switching to main branch.", + "timestamp": "2026-05-18T07:15:27.942267" + } + }, + "last_updated": "2026-05-18T07:15:30.558391" +} \ No newline at end of file diff --git a/agent/agent_runtime_helpers.py b/agent/agent_runtime_helpers.py index b5c70392946..854145525d0 100644 --- a/agent/agent_runtime_helpers.py +++ b/agent/agent_runtime_helpers.py @@ -1109,6 +1109,13 @@ def anthropic_prompt_cache_policy( model_lower = eff_model.lower() provider_lower = eff_provider.lower() is_claude = "claude" in model_lower + # Kimi / Moonshot family via OpenRouter: same cache_control wire format + # as Claude on OpenRouter (envelope layout). Without this branch + # moonshotai/kimi-k2.6 falls through to (False, False), serving ~1% + # cache hits on 64K-token prompts and re-billing the full prompt on + # every turn. Observed within-turn progression with cache enabled: + # 1% → 67% → 84% → 97% (#25970). + is_kimi = "kimi" in model_lower or "moonshot" in model_lower is_openrouter = base_url_host_matches(eff_base_url, "openrouter.ai") # Nous Portal proxies to OpenRouter behind the scenes — identical # OpenAI-wire envelope cache_control semantics. Treat it as an @@ -1122,7 +1129,7 @@ def anthropic_prompt_cache_policy( if is_native_anthropic: return True, True - if (is_openrouter or is_nous_portal) and is_claude: + if (is_openrouter or is_nous_portal) and (is_claude or is_kimi): return True, False # Nous Portal Qwen (e.g. qwen3.6-plus) takes the same envelope-layout # cache_control path as Portal Claude. Portal proxies to OpenRouter diff --git a/analyzed_issues.json b/analyzed_issues.json new file mode 100644 index 00000000000..ff69e642ea8 --- /dev/null +++ b/analyzed_issues.json @@ -0,0 +1,117 @@ +{ + "27198": { + "title": "[Bug]: WhatsApp messages stuck at 1 tick — delivery ACK missing in addition to read receipts", + "url": "https://github.com/NousResearch/hermes-agent/issues/27198", + "seen_at": "2026-05-17T01:45:29.080613+00:00" + }, + "27166": { + "title": "[Bug] Telegram DM topic response routed to All Messages after session split", + "url": "https://github.com/NousResearch/hermes-agent/issues/27166", + "seen_at": "2026-05-17T01:45:29.080852+00:00" + }, + "27156": { + "title": "Session resume can replay prior assistant/tool context instead of answering exact-output prompt", + "url": "https://github.com/NousResearch/hermes-agent/issues/27156", + "seen_at": "2026-05-17T01:45:29.081027+00:00" + }, + "27312": { + "title": "Browser tool should prefer packaged agent-browser native binary when npm shim needs unavailable node", + "url": "https://github.com/NousResearch/hermes-agent/issues/27312", + "seen_at": "2026-05-17T07:46:52.354983+00:00" + }, + "27296": { + "title": "[Bug] delegate_task ignores delegation.base_url — subagent always inherits parent model", + "url": "https://github.com/NousResearch/hermes-agent/issues/27296", + "seen_at": "2026-05-17T07:46:52.355896+00:00" + }, + "27295": { + "title": "[Bug] delegate_task ignores delegation.base_url — subagent always inherits parent model", + "url": "https://github.com/NousResearch/hermes-agent/issues/27295", + "seen_at": "2026-05-17T07:46:52.357442+00:00" + }, + "27294": { + "title": "[Bug] delegate_task ignores delegation.base_url — subagent always inherits parent model", + "url": "https://github.com/NousResearch/hermes-agent/issues/27294", + "seen_at": "2026-05-17T07:46:52.358251+00:00" + }, + "27282": { + "title": "[--tui] gateway exits mid-turn with stdin EOF (TUI closed the command pipe) — NOT byterover-related", + "url": "https://github.com/NousResearch/hermes-agent/issues/27282", + "seen_at": "2026-05-17T07:46:52.359345+00:00" + }, + "27265": { + "title": "Discord long bot-to-bot handoffs can drop unmentioned continuation chunks", + "url": "https://github.com/NousResearch/hermes-agent/issues/27265", + "seen_at": "2026-05-17T07:46:52.360103+00:00" + }, + "27230": { + "title": "[Bug]: Telegram gateway only acknowledges tool requests but never delivers final results", + "url": "https://github.com/NousResearch/hermes-agent/issues/27230", + "seen_at": "2026-05-17T07:46:52.361212+00:00" + }, + "27430": { + "title": "hermes update fails web UI build when NODE_ENV=production — npm install omits devDependencies", + "url": "https://github.com/NousResearch/hermes-agent/issues/27430", + "seen_at": "2026-05-17T13:48:05.033485+00:00" + }, + "27402": { + "title": "NameError: '_pool_may_recover_from_rate_limit' is not defined in conversation_loop.py", + "url": "https://github.com/NousResearch/hermes-agent/issues/27402", + "seen_at": "2026-05-17T13:48:05.071950+00:00" + }, + "27383": { + "title": "[Bug]: change working directory for Telegram agent", + "url": "https://github.com/NousResearch/hermes-agent/issues/27383", + "seen_at": "2026-05-17T13:48:05.073121+00:00" + }, + "27352": { + "title": "[Bug] Gateway approval wait is not resolved by normal user replies during pending approval", + "url": "https://github.com/NousResearch/hermes-agent/issues/27352", + "seen_at": "2026-05-17T13:48:05.074324+00:00" + }, + "27345": { + "title": "[Bug]: API connection Fail with minimax provider in windows", + "url": "https://github.com/NousResearch/hermes-agent/issues/27345", + "seen_at": "2026-05-17T13:48:05.075138+00:00" + }, + "27566": { + "title": "Context compression triggers every turn due to rough token estimate inflating last_prompt_tokens", + "url": "https://github.com/NousResearch/hermes-agent/issues/27566", + "seen_at": "2026-05-17T19:48:41.166309+00:00" + }, + "27563": { + "title": "Python shutdown deadlock: worker thread blocks Py_FinalizeEx, process hangs forever after exit", + "url": "https://github.com/NousResearch/hermes-agent/issues/27563", + "seen_at": "2026-05-17T19:48:41.167190+00:00" + }, + "27555": { + "title": "Bug: vision fallback_chain silently broken — wrong kwargs in _resolve_single_provider", + "url": "https://github.com/NousResearch/hermes-agent/issues/27555", + "seen_at": "2026-05-17T19:48:41.168199+00:00" + }, + "27540": { + "title": "[Bug]: AIAgent() got multiple values for keyword argument 'model' — reproduces on second turn of session", + "url": "https://github.com/NousResearch/hermes-agent/issues/27540", + "seen_at": "2026-05-17T19:48:41.168926+00:00" + }, + "27538": { + "title": "auxiliary.compression.provider ignored after switching model provider", + "url": "https://github.com/NousResearch/hermes-agent/issues/27538", + "seen_at": "2026-05-17T19:48:41.170045+00:00" + }, + "27529": { + "title": "[feishu] Fix markdown table rendering: use post+tag:md instead of force-text workaround", + "url": "https://github.com/NousResearch/hermes-agent/issues/27529", + "seen_at": "2026-05-17T19:48:41.170928+00:00" + }, + "27477": { + "title": "[Bug] Feishu 转发聊天记录无法被 Hermes 读取", + "url": "https://github.com/NousResearch/hermes-agent/issues/27477", + "seen_at": "2026-05-17T19:48:41.172039+00:00" + }, + "27469": { + "title": "[feishu] Unified fix for markdown rendering: inbound escaping + GFM table → Card 2.0", + "url": "https://github.com/NousResearch/hermes-agent/issues/27469", + "seen_at": "2026-05-17T19:48:41.173084+00:00" + } +} \ No newline at end of file diff --git a/scripts/phase_tracker.py b/scripts/phase_tracker.py new file mode 100644 index 00000000000..6ac28a1d1df --- /dev/null +++ b/scripts/phase_tracker.py @@ -0,0 +1,445 @@ +#!/usr/bin/env python3 +""" +Phase Tracker — strict multi-template phase enforcement for upstream contributions. + +Usage: + phase_tracker.py start