Prompt file imported from sho-kawasaki-dd/gem-read (
.github/prompts/plan-staleCacheMismatchFix.prompt.md). Copyright stays with the author.
Plan: Stale Cache Mismatch Fix
æ¢å cache ã¯åå©çšããçŸè¡ä»æ§ãç¶æãã€ã€ãremote åŽã§ article cache ã倱ãããã®ã« extension ã active cache ãšããŠæ±ãç¶ããäžæŽåãè§£æ¶ãããæšå¥šæ¹éã¯ãPython/browser_api ããcache ä»ãå®è¡ã¯å€±æã uncached fallback ã§æåãããäºå®ãå¿çã¡ã¿ããŒã¿ãšããŠè¿ããbrowser-extension åŽã§ãã® cache ã remote-missing ãšã㊠local state ãã invalidated ã«èœãšãããšãããã«ãã PowerShell äžã® 403 fallback ãã°ãš overlay 衚瀺ãäžèŽãããåã stale cache ãæ¬¡å以éãåéããªãããã«ããã
Steps
- Phase 1: Python ã® analyze çµè·¯ã§ cache fallback æåã芳枬å¯èœã«ãããsrc/pdf_epub_reader/models/ai_model.py ã®
AIModel.analyze()ã§ãcached_contentãä»ããå®è¡ã詊ã¿ããã倱æåŸã« cache ãªãã§ fallback ãããããã®çç±ãäœãã local 倿°ãšããŠä¿æããçµæ DTOïŒsrc/pdf_epub_reader/dto/ai_dto.py ã®AnalysisResultïŒãžæµãã圢ã«ãããæ¢åã®ãfallback ã§æåããããæåèªäœã¯å€ããªãããªãuse_explicit_cache=TrueïŒãã©ãŠã¶æ¡åŒµã®éåžžãã¹ïŒã® fallback æã¯self._cache_name/self._cache_modelãã¯ãªã¢ããªãçŸè¡å®è£ ã¯æå³çãªãã®ã§ãã倿Žããªãã - Phase 1: browser_api ã® application DTO ãš HTTP schema ãæ¡åŒµãããsrc/browser_api/application/dto.py ã®
AnalyzeTranslateResultãš src/browser_api/api/schemas/analyze.py ã®AnalyzeTranslateResponseã«ãå°ãªããšãcache_request_attemptedãcache_request_failedãcache_fallback_reasonçžåœã® optional metadata ã远å ããæ¢åã¯ã©ã€ã¢ã³ãäºæãä¿ã£ããŸãŸã·ãªã¢ã©ã€ãºãããStep 1 ã«äŸåã - Phase 1: browser_api service ãæ°ã¡ã¿ããŒã¿ãå¿çãžèŒããããã«ãããsrc/browser_api/application/services/analyze_service.py ã®
analyze_translate()ãšé¢é£å€æåŠçã§ãAIModel ããæ¥ã cache fallback metadata ãAnalyzeTranslateResultã«è©°ãããæ¢åã®used_mock/degraded_reasonãšã¯æå³ãæ··ããªããStep 1-2 ã«äŸåã - Phase 2: extension ã®å
±æ contract ãš gateway ã§ metadata ãåãåããbrowser-extension/src/shared/contracts/messages.ts ã®
AnalyzeApiResponseãš browser-extension/src/shared/gateways/localApiGateway.ts ã®ã¬ã¹ãã³ã¹å€æã«ãbrowser_api ããæ¥ã cache fallback metadata ã远å ãããsnake_case â camelCase 倿ãããã§åžåãããStep 2-3 ã«äŸåã - Phase 2: background ã§ stale cache ã local invalidated ã«èœãšããbrowser-extension/src/background/usecases/runSelectionAnalysis.ts ã§
sendAnalyzeTranslateRequest()ã®æ»ãå€ãèŠãŠãcacheRequestFailed=trueã〠fallback success ã®å Žåã¯invalidateArticleCache()ãåŒã³ session ã®articleCacheStateãremote-missingçç±ã§ invalidated ã«æŽæ°ãããæŽæ°åŸã® session ãªããžã§ã¯ããsetAnalysisSessionãšåŸç¶ã®renderOverlayäž¡æ¹ã«æž¡ãããšïŒæŽæ°åã® session ãäžæžãããã«æž¡ããš overlay ãå€ã active 衚瀺ã®ãŸãŸæ®ãïŒã次åãªã¯ãšã¹ãã§ stalecacheNameãåéãããªãç¹ã¯resolveExplicitCacheName()ãstatus !== 'active'ãªãundefinedãè¿ãæ¢åããžãã¯ã§èªåçã«éæãããããã远å ããžãã¯ã¯äžèŠãStep 4 ã«äŸåã - Phase 2: article cache service ã® invalidation reason ãš notice ãæŽãããbrowser-extension/src/background/services/articleCacheService.ts ã®
invalidateTrackedState()ã¯çŸç¶cacheNameããããšå¿ ãdeleteContextCache()ãåŒã¶ããremote-missingã®å Žå㯠Gemini åŽã«ãã£ãã·ã¥ãååšããªããããªã¢ãŒãåé€åŒã³åºã㯠404 çã§å€±æãstatus: 'degraded'ã«èœã¡ããreason === 'remote-missing'ã®å Žåã¯ãªã¢ãŒãåé€ãã¹ãããããŠããŒã«ã« state ã ããinvalidatedã«æŽæ°ãããã¹ãæ°èšããããšãnotice ã¯ããµãŒããŒåŽã§ article cache ãèŠã€ãããªãã£ããããä»åã®ãªã¯ãšã¹ã㯠cache ãªãã§å®äºãããæ¹åãžçµ±äžããæ¢åã®Article cache created automatically for the current tab.ã stale state ã®ãŸãŸæ®ããªãããã«ãããStep 5 ã«äŸåã - Phase 3: overlay 衚瀺ã state ã«åãããŠèª¿æŽãããbrowser-extension/src/content/overlay/renderOverlay.ts ã®
buildBannerText()ãformatArticleCacheStatus()ãbuildCacheImpactValue()ãbuildCacheImpactNote()ã§ãinvalidated + remote-missingã®å Žåã«å®æåã«åãæèšãžåãæ¿ãããactive cache ãæ¬åœã«äœ¿ãããå Žåã®è¡šç€ºã¯ç¶æããfallback æåæã ããcache ã¯ä»å䜿ãããªãã£ãããšåããããã«ãããStep 6 ã«äŸåã - Phase 4: Python åŽãã¹ãã远å ãããtests/test_models/test_ai_model.py ã§ cache request failure â uncached fallback success ã®ã±ãŒã¹ã« metadata ãç«ã€ããšãæ€èšŒããtests/test_browser_api/test_application/test_analyze_service.py ãš tests/test_browser_api/test_api/test_analyze_router.py ã§ browser_api çµç±ã®å¿ç JSON ã«æ°ãã£ãŒã«ããèŒãããšã確èªãããStep 1-3 ã«äŸåã
- Phase 4: extension åŽãã¹ãã远å ãããbrowser-extension/tests/unit/shared/localApiGateway.test.ts ã« metadata 倿ïŒsnake_case â camelCaseïŒã®ã±ãŒã¹ã远å ããbrowser-extension/tests/unit/background/runSelectionAnalysis.test.ts ã§ fallback success åŸã« local cache state ã
remote-missinginvalidated ãžèœã¡ãæŽæ°åŸã® state ã overlay ãžåæ ãããããšã確èªãããbrowser-extension/tests/unit/background/articleCacheService.test.ts ã§remote-missingreason æã«ãªã¢ãŒãåé€ãåŒã°ããããŒã«ã« state ã ããinvalidatedã«ãªãããšã確èªããbrowser-extension/tests/unit/content/renderOverlay.test.ts ã§ notice / status è¡šç€ºãæ°ç¶æ ã«äžèŽããããšãåºå®ãããStep 4-7 ã«äŸåã - Phase 5: ããã¥ã¡ã³ããæŽæ°ãããdocs/user/settings-and-cache.md ã§ãæ¢å cache ã¯åå©çšããããserver åŽã§ cache ã倱ãããå Žåã¯ããŒã«ã« state ãç¡å¹åããä»åã®ãªã¯ãšã¹ã㯠cache ãªãã§å®äºããæšã瀺ããããšã远èšããå¿ èŠãªã docs/developer/runtime-flows.md ã« fallback metadata â invalidation ã®æµããè£è¶³ãããStep 7 ã«äŸåã
Relevant files
- d:\programming\py_apps\gem-read\src\pdf_epub_reader\models\ai_model.py â
AIModel.analyze()ã® cache fallback æåã芳枬ã»èšé²ããèµ·ç¹ã - d:\programming\py_apps\gem-read\src\pdf_epub_reader\dto\ai_dto.py â
AnalysisResultdataclass ã« fallback metadata ãã£ãŒã«ãã远å ãã倿Žå ãai_model.pyãã gateway çµç±ã§ service ãŸã§äŒæ¬ããäžç¶ DTOã - d:\programming\py_apps\gem-read\src\browser_api\application\dto.py â
AnalyzeTranslateResultã® metadata æ¡åŒµå ã - d:\programming\py_apps\gem-read\src\browser_api\api\schemas\analyze.py â HTTP response schema ã®æ¡åŒµå ã
- d:\programming\py_apps\gem-read\src\browser_api\application\services\analyze_service.py â AIModel çµæã browser_api response ãžãããã³ã°ããç®æã
- d:\programming\py_apps\gem-read\browser-extension\src\shared\contracts\messages.ts â
AnalyzeApiResponseãšArticleCacheInvalidationReasonã® contract æŽæ°å ã - d:\programming\py_apps\gem-read\browser-extension\src\shared\gateways\localApiGateway.ts â API response metadata ã®ãã·ãªã¢ã©ã€ãºå ã
- d:\programming\py_apps\gem-read\browser-extension\src\background\usecases\runSelectionAnalysis.ts â fallback success ãåã㊠local article cache state ãç¡å¹åããæ¬åœã
- d:\programming\py_apps\gem-read\browser-extension\src\background\services\articleCacheService.ts â
remote-missingnotice ãš invalidation helper ã®æŽåå ã - d:\programming\py_apps\gem-read\browser-extension\src\content\overlay\renderOverlay.ts â banner / status / cache impact ã®æèšæŽåå ã
- d:\programming\py_apps\gem-read\tests\test_models\test_ai_model.py â AIModel ã® fallback metadata ååž°é²æ¢ã
- d:\programming\py_apps\gem-read\tests\test_browser_api\test_application\test_analyze_service.py â service 局㮠metadata ååž°é²æ¢ã
- d:\programming\py_apps\gem-read\tests\test_browser_api\test_api\test_analyze_router.py â HTTP schema ã®ååž°é²æ¢ã
- d:\programming\py_apps\gem-read\browser-extension__tests__\unit\background\runSelectionAnalysis.test.ts â stale cache invalidation ã®ååž°é²æ¢ã
- d:\programming\py_apps\gem-read\browser-extension__tests__\unit\background\articleCacheService.test.ts â
remote-missingstate ã® notice/transition ååž°é²æ¢ã - d:\programming\py_apps\gem-read\browser-extension__tests__\unit\content\renderOverlay.test.ts â overlay 衚瀺æèšã®ååž°é²æ¢ã
- d:\programming\py_apps\gem-read\docs\user\settings-and-cache.md â ãŠãŒã¶ãŒåã仿§ã®æŽæ°å ã
- d:\programming\py_apps\gem-read\docs\developer\runtime-flows.md â runtime flow ã®è£è¶³å ã
Verification
- Python åŽã§ãcache ä»ãå®è¡ã 403 / 400 çã§å€±æã uncached fallback ã§æåããã±ãŒã¹ã®åäœãã¹ããéãããšã確èªããã
- browser_api ã®ã¬ã¹ãã³ã¹ JSON ã«æ° metadata ãèŒããæ§ã¯ã©ã€ã¢ã³ãäºæãå£ããŠããªãããšã確èªããã
- extension ã® unit test ã§ãfallback success åŸã« local article cache state ã
remote-missinginvalidated ã«æŽæ°ãããæ¬¡åãªã¯ãšã¹ãã§ã¯ stale cacheName ãéããªãããšã確èªããã - overlay ã§
Article cache created automatically for the current tab.ã stale state ã®ãŸãŸæ®ããããä»åã®ãªã¯ãšã¹ã㯠cache ãªãã§å®äºãããæ¹åã®æèšãžåãæ¿ããããšã確èªããã - popup ã® article cache toggle ã OFF ã«ããŠããŠããæ£åžžãªæ¢å cache ã¯åå©çšãããäžæ¹ãserver åŽã§æ¶ãã cache ã ã㯠local invalidation ãããããšãæå確èªããã
- å床åãããŒãžã§å®è¡ãããšããinvalidated æžã¿ stale cacheName ãåéããããPowerShell äžã®åäž 403 fallback ãã°ãæ¯åç¹°ãè¿ãããªãããšã確èªããã
Decisions
- popup toggle OFF åŸãæ¢å cache ã¯åå©çšããçŸè¡ä»æ§ãç¶æããã
- cache ä»ãå®è¡ã倱æã uncached fallback ãæåããå Žåããã® cache 㯠local state ã
remote-missingçç±ã§ invalidated ã«èœãšãã - stale remote cache ã¯æ¬¡åãåéããªãã
invalidateArticleCache()ã§statusãinvalidatedã«èœãšãã°resolveExplicitCacheName()ã®æ¢åã¬ãŒãã«ããcacheNameã¯èªåçã«éãããªããªãã - Python/browser_api ãžã¯ optional response metadata ã远å ã㊠extension ãžäºå®ãäŒããã
- overlay æèšã¯ãcache äœææžã¿ãã§ã¯ãªããserver åŽã§ cache ãèŠã€ãããä»å㯠cache ãªãã§å®äºãããã«å¯ããã
Further Considerations
cache_fallback_reasonã¯çã® Gemini message å šæã§ã¯ãªããUI ã§ã¯çã reason code ãæ£èŠåããã説æã ããåºãæ¹ã stableã詳现ãã°ã¯ Python logger ã«æ®ããremote-missinginvalidation æã«displayNameãtokenEstimateãã©ããŸã§æ®ããã¯å°å€æã次å stale cache ãåå©çšããªãããšãåªå ãããªãcacheNameã¯ç¢ºå®ã«èœãšãã衚瀺çšã¡ã¿ã¯å¿ èŠæäœéã ãæ®ãã®ãå®å šã