-
初始激活序列 ({{ simulationConfig.event_config.initial_posts.length }})
+
{{ $t('step2.initialPosts') }} ({{ simulationConfig.event_config.initial_posts.length }})
@@ -423,29 +423,29 @@
POST /api/simulation/start
-
模拟环境已准备完成,可以开始运行模拟
+
{{ $t('step2.desc5') }}
@@ -454,10 +454,10 @@
{{ customMaxRounds }}
- 轮
+ {{ $t('step2.rounds') }}
- 若Agent规模为100:预计耗时约 {{ Math.round(customMaxRounds * 0.6) }} 分钟
+ {{ $t('step2.estTime', { n: Math.round(customMaxRounds * 0.6) }) }}
@@ -478,7 +478,7 @@
:class="{ active: customMaxRounds === 40 }"
@click="customMaxRounds = 40"
:style="{ position: 'absolute', left: `calc(${(40 - 10) / (autoGeneratedRounds - 10) * 100}% - 30px)` }"
- >40 (推荐)
+ >40 ({{ $t('step2.recOver40') }})
{{ autoGeneratedRounds }}
@@ -488,7 +488,7 @@
{{ autoGeneratedRounds }}
- 轮
+ {{ $t('step2.rounds') }}
-
若首次运行,强烈建议切换至‘自定义模式’减少模拟轮数,以便快速预览效果并降低报错风险 ➝
+
{{ $t('step2.customTip') }}
@@ -514,14 +514,14 @@
class="action-btn secondary"
@click="$emit('go-back')"
>
- ← 返回图谱构建
+ {{ $t('step2.backToGraph') }}
@@ -547,19 +547,19 @@
- 事件外显年龄
- {{ selectedProfile.age || '-' }} 岁
+ {{ $t('step2.age') }}
+ {{ selectedProfile.age || '-' }} {{ $t('step2.years') }}
- 事件外显性别
- {{ { male: '男', female: '女', other: '其他' }[selectedProfile.gender] || selectedProfile.gender }}
+ {{ $t('step2.gender') }}
+ {{ { male: $t('step2.male'), female: $t('step2.female'), other: $t('step2.other') }[selectedProfile.gender] || selectedProfile.gender }}
- 国家/地区
+ {{ $t('step2.country') }}
{{ selectedProfile.country || '-' }}
- 事件外显MBTI
+ {{ $t('step2.mbti') }}
{{ selectedProfile.mbti || '-' }}
diff --git a/frontend/src/components/Step3Simulation.vue b/frontend/src/components/Step3Simulation.vue
index 74d0e1e7..a6a133db 100644
--- a/frontend/src/components/Step3Simulation.vue
+++ b/frontend/src/components/Step3Simulation.vue
@@ -97,7 +97,7 @@
@click="handleNextStep"
>
- {{ isGeneratingReport ? '启动中...' : '开始生成结果报告' }}
+ {{ isGeneratingReport ? $t('step3.starting') : $t('step3.startReport') }}
→
diff --git a/frontend/src/i18n/index.js b/frontend/src/i18n/index.js
new file mode 100644
index 00000000..43ba3252
--- /dev/null
+++ b/frontend/src/i18n/index.js
@@ -0,0 +1,31 @@
+import { createI18n } from 'vue-i18n'
+import zh from './locales/zh'
+import en from './locales/en'
+
+const LOCALE_KEY = 'mirofish-locale'
+
+export function getStoredLocale() {
+ try {
+ const stored = localStorage.getItem(LOCALE_KEY)
+ if (stored === 'zh' || stored === 'en') return stored
+ } catch (_) {}
+ return 'zh'
+}
+
+export function setStoredLocale(locale) {
+ try {
+ localStorage.setItem(LOCALE_KEY, locale)
+ } catch (_) {}
+}
+
+const i18n = createI18n({
+ legacy: false, // Use Composition API mode
+ locale: getStoredLocale(),
+ fallbackLocale: 'zh',
+ messages: {
+ zh,
+ en,
+ },
+})
+
+export default i18n
diff --git a/frontend/src/i18n/locales/en.js b/frontend/src/i18n/locales/en.js
new file mode 100644
index 00000000..d4109239
--- /dev/null
+++ b/frontend/src/i18n/locales/en.js
@@ -0,0 +1,211 @@
+/**
+ * English locale
+ */
+export default {
+ common: {
+ loading: 'Loading...',
+ error: 'Error',
+ refresh: 'Refresh',
+ close: 'Close',
+ none: 'None',
+ unknown: 'Unknown',
+ },
+ nav: {
+ visitGithub: 'Visit our GitHub',
+ language: 'Language',
+ zh: '中文',
+ en: 'English',
+ },
+ home: {
+ tagline: 'Simple & Universal Swarm Intelligence Engine',
+ version: '/ v0.1-preview',
+ title1: 'Upload Any Report',
+ title2: 'Predict the Future Instantly',
+ desc1: 'With just a paragraph of text, ',
+ desc2: 'MiroFish',
+ desc3: ' can automatically generate a parallel world powered by up to ',
+ desc4: 'millions of Agents',
+ desc5: ' from the seeds of reality within. Inject variables from a god\'s-eye view and find ',
+ desc6: '"local optima"',
+ desc6Suffix: ' in complex group interactions under dynamic environments.',
+ slogan: 'Let the future be rehearsed in Agent swarms, let decisions win after a hundred battles.',
+ systemStatus: 'System Status',
+ ready: 'Ready',
+ readyDesc: 'Prediction engine on standby. Upload unstructured data to initialize simulation sequence.',
+ lowCost: 'Low Cost',
+ lowCostDesc: 'Avg. ~5$/run for typical simulations',
+ highAvailable: 'High Scale',
+ highAvailableDesc: 'Up to millions of Agents',
+ workflow: 'Workflow Sequence',
+ step1Title: 'Graph Build',
+ step1Desc: 'Reality seed extraction & individual/group memory injection & GraphRAG construction',
+ step2Title: 'Env Setup',
+ step2Desc: 'Entity-relation extraction & persona generation & simulation params injection',
+ step3Title: 'Simulation',
+ step3Desc: 'Dual-platform parallel simulation & auto-parse prediction needs & dynamic memory update',
+ step4Title: 'Report',
+ step4Desc: 'ReportAgent has rich tools for deep interaction with post-simulation environment',
+ step5Title: 'Interaction',
+ step5Desc: 'Chat with any agent in the simulated world & interact with ReportAgent',
+ seedLabel: '01 / Reality Seed',
+ formatHint: 'Supported: PDF, MD, TXT',
+ dragUpload: 'Drag files to upload',
+ clickBrowse: 'or click to browse',
+ inputParams: 'Input Parameters',
+ promptLabel: '>_ 02 / Simulation Prompt',
+ promptPlaceholder: '// Enter your simulation or prediction needs in natural language (e.g. What if Wuhan Univ. releases a revocation of Xiao\'s penalty? How would public sentiment shift?)',
+ engineBadge: 'Engine: MiroFish-V1.0',
+ startEngine: 'Start Engine',
+ initializing: 'Initializing...',
+ },
+ mainView: {
+ graph: 'Graph',
+ split: 'Split',
+ workbench: 'Workbench',
+ stepGraph: 'Graph Build',
+ stepEnv: 'Env Setup',
+ stepSim: 'Simulation',
+ stepReport: 'Report',
+ stepInteraction: 'Interaction',
+ statusReady: 'Ready',
+ statusBuilding: 'Building Graph',
+ statusOntology: 'Generating Ontology',
+ statusInit: 'Initializing',
+ },
+ history: {
+ title: 'History',
+ graphBuild: 'Graph Build',
+ envSetup: 'Env Setup',
+ report: 'Report',
+ moreFiles: ' files',
+ noFiles: 'No files',
+ noName: 'Unnamed simulation',
+ notStarted: 'Not started',
+ rounds: ' rounds',
+ simRequirement: 'Simulation Requirement',
+ relatedFiles: 'Related Files',
+ noRelatedFiles: 'No related files',
+ unknownFile: 'Unknown file',
+ playback: 'Playback',
+ graphBuildBtn: 'Graph Build',
+ envSetupBtn: 'Env Setup',
+ reportBtn: 'Report',
+ playbackHint: 'Step3 "Simulation" and Step5 "Interaction" must be started during runtime; no history playback.',
+ },
+ graph: {
+ refresh: 'Refresh graph',
+ maximize: 'Maximize / Restore',
+ updating: 'Updating...',
+ memoryUpdating: 'GraphRAG memory updating',
+ hintRefresh: 'Some content still processing. Refresh the graph manually later.',
+ loadingGraph: 'Loading graph...',
+ waitOntology: 'Waiting for ontology...',
+ closeHint: 'Close',
+ nodeDetails: 'Node Details',
+ relationship: 'Relationship',
+ name: 'Name',
+ created: 'Created',
+ properties: 'Properties',
+ summary: 'Summary',
+ labels: 'Labels',
+ },
+ step1: {
+ ontology: 'Ontology',
+ completed: 'Completed',
+ processing: 'Processing',
+ waiting: 'Pending',
+ desc: 'LLM analyzes documents and simulation needs, extracts reality seeds, and generates suitable ontology structure.',
+ analyzing: 'Analyzing documents...',
+ graphBuild: 'GraphRAG Build',
+ desc2: 'Build knowledge graph from documents via Zep, extract entities and relations, form temporal memory and community summaries.',
+ entityNodes: 'Entity nodes',
+ relationEdges: 'Relation edges',
+ schemaTypes: 'SCHEMA types',
+ buildComplete: 'Build Complete',
+ inProgress: 'In progress',
+ descNext: 'Graph build complete. Proceed to environment setup.',
+ enterEnvSetup: 'Enter Env Setup ➝',
+ creating: 'Creating...',
+ },
+ step2: {
+ simInstance: 'Simulation Instance Init',
+ init: 'Initializing',
+ desc1: 'Create simulation instance and fetch world parameter templates.',
+ taskDone: 'Async task completed',
+ agentProfiles: 'Generate Agent Personas',
+ desc2: 'Use tools to extract entities and relations from knowledge graph, initialize individuals, and assign behaviors and memories from reality seeds.',
+ agentCount: 'Current Agents',
+ expectedAgents: 'Expected Total',
+ topicCount: 'Related Topics',
+ generatedProfiles: 'Generated Agent Personas',
+ unknownProfession: 'Unknown',
+ noBio: 'No bio',
+ dualPlatformConfig: 'Generate Dual-Platform Simulation Config',
+ desc3: 'LLM intelligently sets world time flow, recommendation algorithm, active time slots, posting frequency, event triggers, etc.',
+ simDuration: 'Simulation Duration',
+ hours: 'hours',
+ perRound: 'Per Round',
+ minutes: 'min',
+ totalRounds: 'Total Rounds',
+ rounds: 'rounds',
+ activePerHour: 'Active per Hour',
+ peakPeriod: 'Peak',
+ workPeriod: 'Work',
+ morningPeriod: 'Morning',
+ lowPeriod: 'Low',
+ agentConfig: 'Agent Config',
+ agentsCount: '',
+ activeTime: 'Active Time',
+ postsPerHour: 'Posts/hr',
+ commentsPerHour: 'Comments/hr',
+ responseDelay: 'Response Delay',
+ activityLevel: 'Activity',
+ sentimentBias: 'Sentiment',
+ influence: 'Influence',
+ recAlgoConfig: 'Recommendation Algorithm',
+ platform1: 'Platform 1: Info Plaza',
+ platform2: 'Platform 2: Topic Community',
+ recencyWeight: 'Recency',
+ popularityWeight: 'Popularity',
+ relevanceWeight: 'Relevance',
+ viralThreshold: 'Viral Threshold',
+ echoChamber: 'Echo Chamber',
+ llmConfig: 'LLM Config Inference',
+ initialActivation: 'Initial Activation',
+ arranging: 'Arranging',
+ desc4: 'Generate initial events and hot topics from narrative direction to bootstrap the simulation world.',
+ narrativeDir: 'Narrative Direction',
+ hotTopics: 'Initial Hot Topics',
+ initialPosts: 'Initial Activation',
+ ready: 'Ready',
+ desc5: 'Environment ready. You can start the simulation.',
+ roundsSetting: 'Simulation Rounds',
+ roundsDesc: 'MiroFish plans {hours}h simulation, {mins} min per round.',
+ custom: 'Custom',
+ estTime: 'If 100 agents: ~{n} min',
+ autoRounds: 'Auto',
+ recOver40: 'Recommended',
+ estTimeAuto: 'If 100 agents: ~{n} min',
+ customTip: 'First run? Switch to Custom to use fewer rounds for a quick preview ➝',
+ backToGraph: '← Back to Graph',
+ startSim: 'Start Dual-World Simulation ➝',
+ age: 'Age',
+ years: 'y',
+ gender: 'Gender',
+ male: 'Male',
+ female: 'Female',
+ other: 'Other',
+ country: 'Country/Region',
+ mbti: 'MBTI',
+ },
+ step3: {
+ startReport: 'Generate Report',
+ starting: 'Starting...',
+ },
+ step4: {
+ generating: 'Generating',
+ },
+ step5: {
+ generating: 'Generating',
+ },
+}
diff --git a/frontend/src/i18n/locales/zh.js b/frontend/src/i18n/locales/zh.js
new file mode 100644
index 00000000..0d356879
--- /dev/null
+++ b/frontend/src/i18n/locales/zh.js
@@ -0,0 +1,210 @@
+/**
+ * Chinese locale - default
+ */
+export default {
+ common: {
+ loading: '加载中...',
+ error: '错误',
+ refresh: '刷新',
+ close: '关闭',
+ none: '无',
+ unknown: '未知',
+ },
+ nav: {
+ visitGithub: '访问我们的Github主页',
+ language: '语言',
+ zh: '中文',
+ en: 'English',
+ },
+ home: {
+ tagline: '简洁通用的群体智能引擎',
+ version: '/ v0.1-预览版',
+ title1: '上传任意报告',
+ title2: '即刻推演未来',
+ desc1: '即使只有一段文字,',
+ desc2: 'MiroFish',
+ desc3: ' 也能基于其中的现实种子,全自动生成与之对应的至多',
+ desc4: '百万级Agent',
+ desc5: '构成的平行世界。通过上帝视角注入变量,在复杂的群体交互中寻找动态环境下的',
+ desc6: '"局部最优解"',
+ slogan: '让未来在 Agent 群中预演,让决策在百战后胜出',
+ systemStatus: '系统状态',
+ ready: '准备就绪',
+ readyDesc: '预测引擎待命中,可上传多份非结构化数据以初始化模拟序列',
+ lowCost: '低成本',
+ lowCostDesc: '常规模拟平均5$/次',
+ highAvailable: '高可用',
+ highAvailableDesc: '最多百万级Agent模拟',
+ workflow: '工作流序列',
+ step1Title: '图谱构建',
+ step1Desc: '现实种子提取 & 个体与群体记忆注入 & GraphRAG构建',
+ step2Title: '环境搭建',
+ step2Desc: '实体关系抽取 & 人设生成 & 环境配置Agent注入仿真参数',
+ step3Title: '开始模拟',
+ step3Desc: '双平台并行模拟 & 自动解析预测需求 & 动态更新时序记忆',
+ step4Title: '报告生成',
+ step4Desc: 'ReportAgent拥有丰富的工具集与模拟后环境进行深度交互',
+ step5Title: '深度互动',
+ step5Desc: '与模拟世界中的任意一位进行对话 & 与ReportAgent进行对话',
+ seedLabel: '01 / 现实种子',
+ formatHint: '支持格式: PDF, MD, TXT',
+ dragUpload: '拖拽文件上传',
+ clickBrowse: '或点击浏览文件系统',
+ inputParams: '输入参数',
+ promptLabel: '>_ 02 / 模拟提示词',
+ promptPlaceholder: '// 用自然语言输入模拟或预测需求(例.武大若发布撤销肖某处分的公告,会引发什么舆情走向)',
+ engineBadge: '引擎: MiroFish-V1.0',
+ startEngine: '启动引擎',
+ initializing: '初始化中...',
+ },
+ mainView: {
+ graph: '图谱',
+ split: '双栏',
+ workbench: '工作台',
+ stepGraph: '图谱构建',
+ stepEnv: '环境搭建',
+ stepSim: '开始模拟',
+ stepReport: '报告生成',
+ stepInteraction: '深度互动',
+ statusReady: 'Ready',
+ statusBuilding: 'Building Graph',
+ statusOntology: 'Generating Ontology',
+ statusInit: 'Initializing',
+ },
+ history: {
+ title: '推演记录',
+ graphBuild: '图谱构建',
+ envSetup: '环境搭建',
+ report: '分析报告',
+ moreFiles: '个文件',
+ noFiles: '暂无文件',
+ noName: '未命名模拟',
+ notStarted: '未开始',
+ rounds: ' 轮',
+ simRequirement: '模拟需求',
+ relatedFiles: '关联文件',
+ noRelatedFiles: '暂无关联文件',
+ unknownFile: '未知文件',
+ playback: '推演回放',
+ graphBuildBtn: '图谱构建',
+ envSetupBtn: '环境搭建',
+ reportBtn: '分析报告',
+ playbackHint: 'Step3「开始模拟」与 Step5「深度互动」需在运行中启动,不支持历史回放',
+ },
+ graph: {
+ refresh: '刷新图谱',
+ maximize: '最大化/还原',
+ updating: '实时更新中...',
+ memoryUpdating: 'GraphRAG长短期记忆实时更新中',
+ hintRefresh: '还有少量内容处理中,建议稍后手动刷新图谱',
+ loadingGraph: '图谱数据加载中...',
+ waitOntology: '等待本体生成...',
+ closeHint: '关闭提示',
+ nodeDetails: 'Node Details',
+ relationship: 'Relationship',
+ name: 'Name',
+ created: 'Created',
+ properties: 'Properties',
+ summary: 'Summary',
+ labels: 'Labels',
+ },
+ step1: {
+ ontology: '本体生成',
+ completed: '已完成',
+ processing: '生成中',
+ waiting: '等待',
+ desc: 'LLM分析文档内容与模拟需求,提取出现实种子,自动生成合适的本体结构',
+ analyzing: '正在分析文档...',
+ graphBuild: 'GraphRAG构建',
+ desc2: '基于生成的本体,将文档自动分块后调用 Zep 构建知识图谱,提取实体和关系,并形成时序记忆与社区摘要',
+ entityNodes: '实体节点',
+ relationEdges: '关系边',
+ schemaTypes: 'SCHEMA类型',
+ buildComplete: '构建完成',
+ inProgress: '进行中',
+ descNext: '图谱构建已完成,请进入下一步进行模拟环境搭建',
+ enterEnvSetup: '进入环境搭建 ➝',
+ creating: '创建中...',
+ },
+ step2: {
+ simInstance: '模拟实例初始化',
+ init: '初始化',
+ desc1: '新建simulation实例,拉取模拟世界参数模版',
+ taskDone: '异步任务已完成',
+ agentProfiles: '生成 Agent 人设',
+ desc2: '结合上下文,自动调用工具从知识图谱梳理实体与关系,初始化模拟个体,并基于现实种子赋予他们独特的行为与记忆',
+ agentCount: '当前Agent数',
+ expectedAgents: '预期Agent总数',
+ topicCount: '现实种子当前关联话题数',
+ generatedProfiles: '已生成的 Agent 人设',
+ unknownProfession: '未知职业',
+ noBio: '暂无简介',
+ dualPlatformConfig: '生成双平台模拟配置',
+ desc3: 'LLM 根据模拟需求与现实种子,智能设置世界时间流速、推荐算法、每个个体的活跃时间段、发言频率、事件触发等参数',
+ simDuration: '模拟时长',
+ hours: '小时',
+ perRound: '每轮时长',
+ minutes: '分钟',
+ totalRounds: '总轮次',
+ rounds: '轮',
+ activePerHour: '每小时活跃',
+ peakPeriod: '高峰时段',
+ workPeriod: '工作时段',
+ morningPeriod: '早间时段',
+ lowPeriod: '低谷时段',
+ agentConfig: 'Agent 配置',
+ agentsCount: ' 个',
+ activeTime: '活跃时段',
+ postsPerHour: '发帖/时',
+ commentsPerHour: '评论/时',
+ responseDelay: '响应延迟',
+ activityLevel: '活跃度',
+ sentimentBias: '情感倾向',
+ influence: '影响力',
+ recAlgoConfig: '推荐算法配置',
+ platform1: '平台 1:广场 / 信息流',
+ platform2: '平台 2:话题 / 社区',
+ recencyWeight: '时效权重',
+ popularityWeight: '热度权重',
+ relevanceWeight: '相关性权重',
+ viralThreshold: '病毒阈值',
+ echoChamber: '回音室强度',
+ llmConfig: 'LLM 配置推理',
+ initialActivation: '初始激活编排',
+ arranging: '编排中',
+ desc4: '基于叙事方向,自动生成初始激活事件与热点话题,引导模拟世界的初始状态',
+ narrativeDir: '叙事引导方向',
+ hotTopics: '初始热点话题',
+ initialPosts: '初始激活序列',
+ ready: '准备完成',
+ desc5: '模拟环境已准备完成,可以开始运行模拟',
+ roundsSetting: '模拟轮数设定',
+ roundsDesc: 'MiroFish 自动规划推演现实 {hours} 小时,每轮代表现实 {mins} 分钟时间流逝',
+ custom: '自定义',
+ estTime: '若Agent规模为100:预计耗时约 {n} 分钟',
+ autoRounds: '自动',
+ recOver40: '>40 (推荐)',
+ estTimeAuto: '若Agent规模为100:预计耗时 {n} 分钟',
+ customTip: '若首次运行,强烈建议切换至\'自定义模式\'减少模拟轮数,以便快速预览效果并降低报错风险 ➝',
+ backToGraph: '← 返回图谱构建',
+ startSim: '开始双世界并行模拟 ➝',
+ age: '事件外显年龄',
+ years: '岁',
+ gender: '事件外显性别',
+ male: '男',
+ female: '女',
+ other: '其他',
+ country: '国家/地区',
+ mbti: '事件外显MBTI',
+ },
+ step3: {
+ startReport: '开始生成结果报告',
+ starting: '启动中...',
+ },
+ step4: {
+ generating: '正在生成',
+ },
+ step5: {
+ generating: '正在生成',
+ },
+}
diff --git a/frontend/src/main.js b/frontend/src/main.js
index c8e37b03..cc3d101e 100644
--- a/frontend/src/main.js
+++ b/frontend/src/main.js
@@ -1,9 +1,11 @@
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
+import i18n from './i18n'
const app = createApp(App)
app.use(router)
+app.use(i18n)
app.mount('#app')
diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue
index afe01a0c..6420c34d 100644
--- a/frontend/src/views/Home.vue
+++ b/frontend/src/views/Home.vue
@@ -4,8 +4,9 @@