Commit Graph

293 Commits

Author SHA1 Message Date
liyizhouAI 8990b60fe5 Fix report citation chip labels 2026-06-08 21:47:31 +08:00
liyizhouAI 5b00fae91e Expand course report agent summary 2026-06-08 21:40:23 +08:00
liyizhouAI 86a8ae629a Route course simulation to interactive summary 2026-06-08 21:20:57 +08:00
liyizhouAI 57263d5337 Preserve completed simulation replay flow 2026-06-08 19:51:36 +08:00
liyizhouAI e1467b53e2 Use realistic personas for cached demo agents 2026-06-08 19:37:57 +08:00
liyizhouAI c5cc5912c0 Refine report citation anchors 2026-06-08 19:21:14 +08:00
liyizhouAI a6a12d7775 Enhance Foresight demo replay and evidence citations 2026-06-08 19:09:16 +08:00
liyizhouAI 91a621be96 fix: remove unsupported limit param from get_all_actions calls 2026-04-17 20:15:09 +08:00
liyizhouAI cd51ebe282 feat: report quality overhaul — concrete data, agent quotes, infographic
- Add SimulationAnalyticsService: direct actions.jsonl access for stats,
  top posts, agent quotes (positive/negative), sentiment breakdown
- Add simulation_analytics tool to ReportAgent ReACT loop
- Rewrite prompts: demand specific numbers, prohibit vague language,
  require verbatim agent quotes (min 5 per section)
- Refactor report_agent.py: extract prompts → report_prompts.py,
  data classes → report_data.py (both under 800 lines)
- Add ReportInfographic.vue: metrics cards, action distribution bars,
  sentiment breakdown, top agents, timeline sparkline
- Add infographic API endpoint: GET /api/report/<id>/infographic
- Pre-compute infographic data during report generation
- Increase max_tokens from 4096 to 8192 for detailed sections
2026-04-17 16:58:53 +08:00
liyizhouAI 9efdced7f2 fix: report prompt alignment + auto-report trigger + failed report redirect
1. Report prompt now extracts user's core questions from simulation_requirement
   and structures the report to directly answer them (e.g. "will it go well?",
   "where are the problems?") instead of generic future-prediction questions.

2. Step3Simulation auto-triggers report generation 1.5s after simulation completes.

3. ReportView auto-redirects to latest successful report when current report
   has failed, via /api/report/check/<simulation_id> endpoint.
2026-04-17 13:16:03 +08:00
liyizhouAI 86106001da feat: auto-trigger report generation after simulation completes
Simulation completion detection now automatically triggers report
generation after a 1.5s delay, eliminating the need for users to
manually click the "generate report" button.
2026-04-17 13:03:23 +08:00
liyizhouAI 2fda12c8a4 fix: report generation uses separate LLM (SiliconFlow) to avoid GLM 429
Report generation now supports REPORT_LLM_* env vars to route report
LLM calls through a separate provider (SiliconFlow Qwen-32B) instead
of sharing the GLM rate limit with simulation. Also passes the report
LLM client to ZepToolsService so tool calls (PanoramaSearch, QuickSearch,
InsightForge, InterviewAgents) use the same provider.
2026-04-17 12:15:28 +08:00
liyizhouAI 8b77a7b9ba fix: report 429 retry + theme toggle on all pages
- LLMClient: increase retries 5→8, backoff 1s→2s, max 30s→60s for GLM rate limit recovery
- Report agent: add 3s delay between sections to avoid sustained 429
- Add theme-toggle-anchor to SimulationRun/Report/Interaction/Replay views
- All pages now have dark/light theme toggle button
2026-04-17 08:36:58 +08:00
liyizhouAI d2b5b17b98 perf: simulation acceleration - filter non-social entities + configurable semaphore
- Filter out non-social entity types (API, SDK, Database, etc.) from agent configs
  reduces agent count ~20%, fewer LLM calls per round
- Make semaphore configurable via SIMULATION_SEMAPHORE env var (default 50, up from 30)
  allows higher concurrent LLM requests for faster round execution
- Reddit semaphore also reads from env var
- Estimated speedup: ~2x (25min → ~12min for 40 rounds)
2026-04-16 23:11:55 +08:00
liyizhouAI b7df4880c8 fix: v0.3.4 - production stability fixes for simulation pipeline
- LLM JSON truncation: add _repair_truncated_json() to handle max_tokens cutoff
- Ontology generation: increase max_tokens 4096→8192 to prevent truncation
- Config generation: parallel batch processing (3 threads × 30 agents/batch) for ~3x speedup
- Rate limit: reduce semaphore 30→8 to avoid GLM API 429 storms
- HuggingFace offline: set HF_HUB_OFFLINE=1 to skip unreachable hf-mirror.com
- Simulation recovery: auto-reset stuck "preparing" states on Flask restart
- Prepare endpoint: handle concurrent prepare requests gracefully
- Frontend: handle page-refresh-during-prepare edge case
- API: return 429 instead of 500 for LLM rate limit errors
2026-04-16 22:44:40 +08:00
liyizhouAI 3bdaeaf5e7 docs: v0.3.3 - PRD rewrite + Graphiti deprecation record + deploy guide
PRD.md:
- Version bumped to v0.3.3
- Architecture diagram: Graphiti → CustomGraphBuilder
- v0.3.3 changelog: CustomGraphBuilder, deploy.sh, CDN SPA fix, COS deploy
- Infrastructure decisions table updated
- Decision log: 4 new entries for 2026-04-16
- Appendix C: Full Graphiti deprecation record (10 patch attempts, why self-built)
- Appendix D: Complete deployment workflow (backend/frontend/CDN/COS)

README.md / README-ZH.md:
- Step 1 description updated: Graphiti → custom builder with 10x concurrency
2026-04-16 13:00:13 +08:00
liyizhouAI 925d2f7ca6 feat: add one-click deploy script
scripts/deploy.sh unifies backend/frontend deployment:
- --backend (default): rsync app+scripts → ubuntu@124.223.92.72:/opt/foresight/backend
  + kill/restart Flask + health check
- --frontend: vite build + coscmd upload to COS bucket foresight-1317962478
  + tccli CDN purge
- --full: both
- --no-restart: skip Flask restart
- --dry-run: preview only

Safety:
- Python syntax check before rsync (aborts on error)
- health check loop after restart (aborts if /health fails 5x)
- rsync --delete excludes __pycache__ / *.pyc / .pytest_cache
- rsync --rsync-path="sudo rsync" for remote permissions
- set -euo pipefail throughout
- "$@" not eval (handles spaces in project path)

Solves:
- Manual deploys of backend bits scattered across sessions missed v0.3
  accelerate methods on server until this was caught in production
- No consistent way to push frontend + purge CDN in one step
2026-04-16 08:21:52 +08:00
liyizhouAI 7443082846 feat: v0.3.2 - CustomGraphBuilder replaces Graphiti for step 2 graph build
End of a long debugging rabbit hole. After ~10 attempts patching Graphiti's
compatibility with non-OpenAI LLMs (GLM, Qwen via SiliconFlow), every fix
uncovered another bug. Made the strategic call to abandon Graphiti entirely
for the graph-build path and write a minimal custom builder.

## Why Graphiti had to go

- Qwen 32B 32K context overflow on cumulative episode retrieval (60K-82K tokens)
- SiliconFlow Qwen 72B also 32K (not 128K as docs implied)
- GLM 4 Flash gives 128K context but triggers "20015 parameter invalid" on
  Graphiti's structured output calls (logprobs in reranker, empty input in
  embedder, nested dict in Neo4j writes)
- Each patch target was 1-2 levels deep in Graphiti internals
- 4 separate monkey-patches (EntityNode.save, bulk_utils, driver layer,
  reranker, embedder) still couldn't cover the extract_nodes path

## New architecture

backend/app/services/custom_graph_builder.py (NEW, 348 lines):
- Uses Foresight's own LLMClient (retry + GLM→Qwen fallback + token tracker)
- 1 LLM call per chunk (Graphiti needed 4-5)
- Single prompt extracts entities + relationships as JSON
- Writes directly to Neo4j via cypher MERGE (no Graphiti dependency)
- Schema identical to what Graphiti produced — downstream get_all_nodes /
  get_all_edges / zep_entity_reader all work unchanged
- ThreadPoolExecutor (10 workers) for concurrent chunk extraction
- Sequential Neo4j writes via shared session (avoids name conflicts in dedup)
- DDL wrapped in try/except (tolerates pre-existing Graphiti indexes)
- Entity name dedup via in-memory map → single uuid per canonical name
- Regex-sanitized label / relation type to prevent cypher injection

backend/app/api/graph.py:
- /api/graph/build endpoint now calls CustomGraphBuilder instead of
  builder.add_text_batches() → client.add_episodes_batch() (the old Graphiti path)

backend/app/services/graph_builder.py:
- _build_graph_worker also updated to use CustomGraphBuilder (dead code path
  but kept in sync)

backend/app/models/project.py:
- Default chunk_size 500 → 250 (to keep individual LLM prompts small)

backend/app/services/graphiti_client.py:
- Kept all monkey-patches for backward compat — they now only affect legacy
  Graphiti code paths that CustomGraphBuilder bypasses entirely:
  * _patch_neo4j_driver (AsyncSession.run nested-dict sanitize)
  * _patch_reranker_for_non_openai (GLM logprobs workaround)
  * _patch_embedder_empty_input (SiliconFlow empty-input guard)
  * _patch_entity_node_ops (EntityNode.save sanitize)
  * _patch_add_nodes_and_edges_bulk_tx (bulk-episode sanitize)
- These are kept for safety; Graphiti code path is no longer invoked in the
  production build flow but methods like add_episode still exist on the class

## Performance

- Sequential: ~194 chunks × 2-5s = 10-15 min
- Concurrent (10 workers): ~194 / 10 × 3-5s = **1-2 min** (5-8x speedup)
- Rate limiting handled by LLMClient retry/backoff, not raw thread contention

## Downstream compatibility

Verified:
- get_all_nodes: MATCH (n:Entity) WHERE n.group_id = $gid RETURN n, labels(n)
- get_all_edges: MATCH (a)-[r]->(b) WHERE r.group_id = $gid RETURN r, type(r)
- get_node / get_node_edges: MATCH by uuid

CustomGraphBuilder writes:
- (n:Entity [optional second label]) with uuid, name, summary, group_id, created_at
- [r:RELATION_TYPE] with uuid, name, fact, group_id, created_at

Schema matches exactly.

## Pipeline wiring

Step 1 ontology generation → Step 2 graph build (CustomGraphBuilder) →
Step 3 profile generation (ZepEntityReader queries Neo4j) → Step 4 simulation

No changes needed downstream of Step 2.
2026-04-16 07:54:07 +08:00
liyizhouAI f1f2ea4ea5 fix: v0.3.1 - 7 bug fixes unblock end-to-end production flow
First successful E2E test uncovered 7 blocking bugs. All fixed and deployed
to production server. User confirmed full pipeline now runs through.

## Bug Fixes

### #1 LLMClient exponential backoff retry
- recognize RateLimitError / 429 / 5xx / 1302 / timeout / connection errors
- 5 retries with 1→2→4→8→16s backoff + random jitter
- file: backend/app/utils/llm_client.py

### #2 GLM → Qwen 32B dual-LLM fallback (ontology generation)
- primary LLM (智谱 GLM-4-Flash) retries exhausted → single attempt fallback to
  SiliconFlow Qwen 2.5-32B via GRAPHITI_LLM_* config
- solves GLM low RPM quota intermittent throttling
- fallback does NOT retry (avoid cascade)
- file: backend/app/services/ontology_generator.py

### #3 Qwen 32K context overflow
- MAX_TEXT_LENGTH_FOR_LLM 50000 → 28000 chars
- ensures prompt+response stays under 32768 tokens
- truncated docs get marker line "[文档已截断以适应 LLM 上下文窗口]"
- file: backend/app/services/ontology_generator.py

### #4 Neo4j entity summary flatten via monkey-patch
- Qwen occasionally returns {summary: {value, type, title, description}}
  which Neo4j rejects (properties must be primitives)
- monkey-patch Neo4jEntityNodeOperations.save / save_bulk
- recursive _flatten_entity_property extracts .value from nested dicts,
  json.dumps as string fallback
- file: backend/app/services/graphiti_client.py

### #5 Frontend stuck at /process/new with no pending state
- pendingUpload is in-memory reactive, lost on refresh / direct URL
- MainView.handleNewProject early-returned on empty state without navigating,
  leaving UI permanently in "waiting for ontology" limbo
- fix: detect empty state, log redirect msg, router.replace to Home after 800ms
- file: frontend/src/views/MainView.vue

### #6 Semaphore 100 → 30 (OASIS simulation)
- high concurrency triggered GLM rate limit cascade during profile/action LLM calls
- drop to 30 eliminates 1302 retries, total runtime impact < 10%
- file: backend/scripts/run_parallel_simulation.py

### #7 SimulationReplayView redesigned to Manus cinematic style
- previous 3-column analyst panel felt like a dashboard, not a replay
- new single-column immersive layout matching Manus's "observation window":
  - top breadcrumb: "Foresight is running Reddit simulation · Round 8/15"
  - main stage: browser chrome + native-style platform post card
    (Reddit subreddit header / Twitter tweet header)
  - action type badges, agent avatars with gradient palettes
  - stage meta bar: per-round action counts by type
- bottom scrubber row: timestamp chip + Jump to live button + live indicator
  (pulsing green dot when sim is running) + step/play/step buttons + 5 speed levels
- bottom task bar: current pipeline step icon/label/progress
- dark theme (#0A0A0B base + #FF5722 accent)
- analyst mode toggle (◫/▦) preserves original 3-column view
- auto-polling every 10s while sim is running, auto-tracks live position
- file: frontend/src/views/SimulationReplayView.vue

## Docs
- PRD.md bumped to v0.3.1 with full hotfix changelog + decision log entries
2026-04-15 13:25:05 +08:00
liyizhouAI 1fef01d979 feat: v0.3 - Manus replay + token tracking + SIGTERM fix + accelerate button
This is the v0.3 milestone commit before the v0.4 big version push.
Major themes: process replay, runtime stability, cost observability.

## New Features

- **Manus-style process replay** (frontend + backend)
  - `GET /api/simulation/<id>/replay` returns full workflow + agents + rounds + aggregate
  - `frontend/src/views/SimulationReplayView.vue` 3-column layout (workflow / actions / stats)
  - bottom scrubber with play/pause/step + 5 speed levels (0.5x-10x)
  - filters out stale actions from previous runs via latest simulation_start timestamp

- **Token usage tracking** (`backend/app/utils/token_tracker.py`)
  - process-wide stage→model→tokens counter
  - LLMClient auto-records prompt/completion tokens after each call
  - stages tagged at API entry: step1_ontology, step2_graph_build, step3_prepare, step5_report
  - `GET /api/usage/summary` for live stats + CNY cost estimate
  - `GET /api/usage/estimate-simulation` for OASIS subprocess estimation
  - pricing table for GLM/SiliconFlow/MiniMax/OpenAI/Anthropic models
  - documented as internal-use, removed from customer-facing builds

- **Step 2 "Skip & Continue" button**
  - lets user stop profile generation early and proceed with what's already generated
  - `simulation_manager.request_accelerate()` + cancel_check in oasis_profile_generator
  - new endpoint `POST /api/simulation/prepare/accelerate`

## Critical Bug Fix

- **SIGTERM no longer kills running simulation subprocess**
  - root cause: `SimulationRunner.register_cleanup()` registered SIGTERM/SIGINT/SIGHUP handlers
    that called `os.killpg` on every tracked sim child, even though spawn already used
    `start_new_session=True` to give children isolated sessions
  - fix: neutered `register_cleanup` to a no-op; `cleanup_all_simulations` itself preserved
    for explicit stop_simulation paths
  - validated: killed Flask backend twice, simulation subprocess kept running
  - impact: hot-reload backend code without interrupting in-flight simulations

## Performance & Tuning

- semaphore 30 → 100 (twitter + reddit) for higher LLM concurrency
- discovered 200 agents as memory/cost/statistical sweet spot for 8G server
  (503 agents OOMs both platforms; 200 agents fits cleanly with 95% confidence margin)

## Documentation

- **PRD.md** rewritten as v0.3 baseline (10 chapters + 2 appendices, 639 lines)
  - product positioning across 3 usage modes (one-shot / model-reuse / SaaS)
  - v0.4 roadmap: domestic platforms (douyin/wechat/xiaohongshu/weibo), fork sim, multi-tenant
  - operational lessons: HF mirror, Tencent PyPI mirror, GLM-4-Flash choice, agent count
  - decision log with dates
  - per-stage token/cost breakdown for typical 200-agent run
- **README.md / README-ZH.md** updated with replay step + Graphiti+Neo4j

## Files Touched

19 files changed, 1105 insertions(+), 246 deletions(-)
2026-04-15 09:37:22 +08:00
liyizhouAI 8088b927f0 fix: accept all Entity nodes from Graphiti (no custom labels)
Graphiti doesn't assign custom labels like Zep does - all nodes get
generic 'Entity' label. Updated filter to accept all named Entity
nodes instead of requiring custom labels like 'Person', 'Organization'.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-04-14 19:13:50 +08:00
liyizhouAI 67f33a2336 perf: 4x speedup for graph building
- Increase chunk size 500→2000 (reduces chunks from ~125 to ~32 for 60K docs)
- Use Graphiti add_episode_bulk for parallel processing (5 episodes per batch)
- Fallback to sequential if bulk fails
- Target: 60K doc graph build in ~10-15 min instead of 45 min

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-04-14 14:09:41 +08:00
liyizhouAI c46a166cf5 fix: CORS duplicate header + Neo4j query + DateTime serialization
- Remove CORS headers from nginx (let Flask-CORS handle it alone)
- Fix Neo4j edge query to match all relationship types (RELATES_TO + MENTIONS)
- Convert Neo4j DateTime objects to strings for JSON serialization
- Add .serena/, .vercel/, .venv_direct/ to gitignore

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-04-14 13:53:47 +08:00
liyizhouAI 339f2f2e50 fix: Neo4j DateTime serialization + match all edge types
- Convert Neo4j DateTime objects to strings via _safe_str() helper
- Query all edge types (RELATES_TO + MENTIONS), not just RELATES_TO
- Fix get_node_edges to match any relationship type

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-04-14 13:38:11 +08:00
liyizhouAI c8eb8711cc chore: ignore playwright-mcp cache files
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-04-14 09:25:37 +08:00
liyizhouAI a245106514 feat: add error recovery UI + HTTPS API endpoint
- Add retry/home buttons when errors occur in graph building
- Improve error messages: Network Error, timeout, missing files
- Clear guidance for users when page refresh loses upload state
- API endpoint switched from HTTP to HTTPS (api.foresight.yizhou.chat)

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-04-13 23:00:15 +08:00
liyizhouAI d5a908077a perf: upgrade Graphiti LLM to Qwen 32B + improve progress feedback
- Upgrade from Qwen2.5-7B to Qwen2.5-32B-Instruct (faster, better quality)
- Add real-time progress messages: "正在处理第 X/Y 个文本块"
- Log per-episode processing time
- Expand progress range from 15-55% to 15-90% (no more episode polling step)
- Add GRAPHITI_LLM_* separate config for graph building LLM

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-04-13 15:31:16 +08:00
liyizhouAI a35ba347f3 fix: use SiliconFlow free LLM+embedding for Graphiti
- Graphiti LLM: SiliconFlow Qwen/Qwen2.5-7B-Instruct (free, supports structured output)
- Graphiti Embedding: SiliconFlow BAAI/bge-m3 (free, OpenAI-compatible)
- MiniMax Coding Plan doesn't support structured output needed by Graphiti
- Separate GRAPHITI_LLM_* config from main LLM_* config
- Remove _wait_for_episodes call (Graphiti processes synchronously)

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-04-13 14:09:26 +08:00
liyizhouAI 05a5ba0775 fix: add MiniMax embedder and reranker for Graphiti
- MiniMaxEmbedder: custom EmbedderClient for MiniMax's non-OpenAI-compatible
  embedding API (uses 'texts' field instead of 'input')
- Pass LLM config to OpenAIRerankerClient to avoid OPENAI_API_KEY requirement
- Both embedder and reranker now use MiniMax API credentials

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-04-13 13:12:30 +08:00
liyizhouAI fff7edce2a feat: migrate from Zep Cloud to self-hosted Graphiti + Neo4j
Replace Zep Cloud ($25/mo) with open-source Graphiti + Neo4j:
- New graphiti_client.py: unified wrapper with sync bridge for async Graphiti
- Modified graph_builder.py: use Graphiti add_episode instead of Zep batch API
- Modified zep_entity_reader.py: Neo4j Cypher queries replace Zep pagination
- Modified zep_tools.py: Graphiti search replaces Zep Cloud search
- Modified zep_graph_memory_updater.py: Graphiti add_episode replaces Zep add
- Modified oasis_profile_generator.py: GraphitiClient replaces Zep client
- Updated config.py: NEO4J_URI/USER/PASSWORD replace ZEP_API_KEY
- Updated requirements.txt: graphiti-core + neo4j replace zep-cloud
- Added PRD.md: product requirements document with token analysis

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-04-13 12:07:32 +08:00
liyizhouAI 4b682f24f4 feat: dark mode full-page responsive layout overrides
Override inner container max-width constraints (.main-content, .dashboard-section,
.content-area, .main-content-area, .panel-wrapper) so dark mode content fills
widescreen displays like light mode does natively.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-04-11 17:32:52 +08:00
liyizhouAI 36e616101a chore: remove accidentally committed venv, add to .gitignore 2026-04-11 16:40:27 +08:00
liyizhouAI ded715feb2 feat: merge upstream i18n + rebrand MiroFish → Foresight 先见之明
- Merge 41 upstream commits (i18n for 7 languages, security fixes, new features)
- Rebrand all MiroFish references to Foresight/先见之明 across 37 files
- Re-apply dark theme CSS overhaul (pure black/gray, no blue tints)
- Re-apply Teleport-based theme toggle (inline with brand, 20px gap)
- Restore Foresight logo and favicon
- Update GitHub links to liyizhouAI/foresight
- Update locale files, README, package.json

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-04-11 16:40:13 +08:00
666ghj fa0f6519b1 docs: rename README-EN.md to README.md as default English documentation 2026-04-02 16:52:29 +08:00
666ghj 0e9420e0f8 docs: rename README.md to README-ZH.md for Chinese documentation 2026-04-02 16:52:29 +08:00
BaiFu 7d07fb7f03
Merge pull request #440 from Ghostubborn/fix/security-deps
fix(security): 修复前端 3 个高危依赖漏洞
2026-04-02 15:17:46 +08:00
ghostubborn 223b283da7 fix(security): upgrade axios, rollup, picomatch to fix 3 high severity vulnerabilities 2026-04-02 15:00:33 +08:00
BaiFu af71244974
Merge pull request #428 from Ghostubborn/feat/i18n
feat(i18n): 添加多语言切换功能,支持中英文
2026-04-02 14:27:04 +08:00
ghostubborn ed465908db fix(i18n): set HTML lang attribute before Vue mounts via inline script 2026-04-02 14:21:09 +08:00
ghostubborn 65df257e19 chore(deps): upgrade vue-i18n from v9 to v11 2026-04-02 14:20:50 +08:00
ghostubborn f2404903d6 fix(i18n): validate Accept-Language header against registered locales 2026-04-02 14:20:15 +08:00
ghostubborn 2421010fe1 fix(i18n): fix English workflow desc font size with correct CSS selectors 2026-04-01 19:11:22 +08:00
ghostubborn 3929c3ade2 fix(i18n): further shorten English metrics and improve workflow layout 2026-04-01 19:07:19 +08:00
ghostubborn 21922da6cc fix(i18n): improve English layout for homepage left-pane and report title
- Add sans-serif font for English left-pane (status, workflow sections)
- Shorten English workflow step descriptions
- Reduce English report title font-size from 36px to 28px
2026-04-01 19:04:38 +08:00
ghostubborn c6cafdd532 fix(i18n): translate world1/world2 platform labels in interview tool display 2026-04-01 18:38:22 +08:00
ghostubborn 5072a2eaa8 feat(i18n): replace Chinese UI text in Step4Report.vue render functions
Only UI display text is replaced. Regex parsing patterns are kept as-is
since they match the backend output format.
2026-04-01 18:35:18 +08:00
ghostubborn 6db3f98a48 fix(i18n): fix English homepage layout with proper font and shorter copy
- Use sans-serif font for English titles, descriptions and navbar
- Shorten English hero text to avoid overflow
- Fix :global() scoped CSS issue that was setting root font-size to 3.5rem
- Use separate unscoped style block for html[lang] selectors
2026-04-01 18:04:05 +08:00
ghostubborn 24e9bee5be feat(i18n): replace all user-visible Chinese logger messages in zep_tools.py
These are shown to users via ConsoleLogger in the report page.
2026-04-01 17:46:39 +08:00
ghostubborn e79569ab4f feat(i18n): replace all user-visible Chinese in report_agent.py
Covers ReportLogger message fields and logger messages shown via ConsoleLogger.
2026-04-01 17:44:52 +08:00
ghostubborn 1d358fc492 feat(i18n): replace expand/collapse Chinese text in Step4Report.vue 2026-04-01 17:44:45 +08:00