Files
Hermes-ui/packages/client/src/i18n/locales/en.ts
T

1268 lines
50 KiB
TypeScript
Raw Normal View History

export default {
// Login
login: {
title: 'Hermes Web UI',
description: 'Enter your access token to continue. Find it in the server startup logs.',
placeholder: 'Access token',
submit: 'Login',
tokenRequired: 'Please enter your access token',
invalidToken: 'Invalid token',
connectionFailed: 'Cannot connect to server',
passwordLogin: 'Password',
tokenLogin: 'Token',
usernamePlaceholder: 'Username',
passwordPlaceholder: 'Password',
credentialsRequired: 'Please enter username and password',
invalidCredentials: 'Invalid username or password',
tooManyAttempts: 'Too many failed attempts, please try again later',
passwordMismatch: 'Passwords do not match',
passwordTooShort: 'Password must be at least 6 characters',
setupSuccess: 'Password login configured successfully',
passwordChanged: 'Password changed successfully',
passwordRemoved: 'Password login removed',
setupPassword: 'Set Up Password Login',
changePassword: 'Change Password',
changeUsername: 'Change Username',
removePasswordLogin: 'Remove',
username: 'Username',
currentPassword: 'Current Password',
newPassword: 'New Password',
confirmPassword: 'Confirm Password',
newUsername: 'New Username',
usernameChanged: 'Username changed successfully',
usernameTooShort: 'Username must be at least 2 characters',
setupDescription: 'Set up a username and password for convenient login. The access token will continue to work as a backup.',
removeConfirm: 'Are you sure you want to remove password login? You will need to use the access token to log in.',
passwordLoginNotConfigured: 'Password login is not configured',
passwordLoginConfigured: 'Password login enabled ({username})',
},
// Common
common: {
loading: 'Loading...',
cancel: 'Cancel',
delete: 'Delete',
edit: 'Edit',
save: 'Save',
retry: 'Retry',
saved: 'Saved',
update: 'Update',
create: 'Create',
saveFailed: 'Save failed',
deleteFailed: 'Delete failed',
ok: 'OK',
copied: 'Copied',
copy: 'Copy',
noData: 'No data',
expired: 'Expired',
fetch: 'Fetch',
add: 'Add',
enable: 'Enable',
disable: 'Disable',
configured: 'Configured',
notConfigured: 'Not configured',
confirm: 'Confirm',
expand: 'Expand',
collapse: 'Collapse',
start: 'Start',
stop: 'Stop',
},
// Sidebar
sidebar: {
chat: 'Chat',
2026-04-22 14:00:34 +08:00
search: 'Search',
apiRelay: 'API Relay',
history: 'History',
jobs: 'Jobs',
2026-05-08 11:32:47 +08:00
kanban: 'Kanban',
models: 'Models',
profiles: 'Profiles',
skills: 'Skills',
2026-05-10 13:50:39 +02:00
plugins: 'Plugins',
memory: 'Memory',
logs: 'Logs',
usage: 'Usage',
skillsUsage: 'Skills Usage',
channels: 'Channels',
gateways: 'Gateways',
terminal: 'Terminal',
groupChat: 'Group Chat',
files: 'Files',
groupConversation: 'Conversation',
groupConversationShort: 'Conv',
groupPlatform: 'Platform',
groupAgent: 'Agent',
groupAgentShort: 'Agent',
groupSystem: 'System',
groupSystemShort: 'Sys',
groupMonitoring: 'Monitoring',
groupMonitoringShort: 'Mon',
groupTools: 'Tools',
settings: 'Settings',
connected: 'Connected',
disconnected: 'Disconnected',
collapse: 'Collapse menu',
expand: 'Expand menu',
updateTip: 'Run "hermes-web-ui update" in terminal to update',
updateVersion: 'Upgrade to v{version}',
reloadClientVersion: 'Reload for v{version}',
updating: 'Updating...',
2026-05-14 12:06:39 +08:00
updateSuccess: 'Update successful. Please refresh the page shortly. If it does not start after a while, start it manually.',
updateFailed: 'Update failed',
logout: 'Sign Out',
nodeVersionWarning: 'Detected Node.js v{version}. Please upgrade to version 23 or later.',
changelog: 'Changelog',
noChangelog: 'No changelog available',
},
2026-05-03 22:10:40 +08:00
// Drawer
drawer: {
terminal: 'Terminal',
files: 'Workspace',
},
// Chat
chat: {
contextRemaining: 'remaining',
contextClickToEdit: 'Click to edit context length',
contextEditTitle: 'Edit Context Length',
contextEditDesc: 'Set context length limit for current model (in tokens)',
contextEditPlaceholder: 'Enter context length',
contextEditHint: 'Common values: 200k (Claude), 128k (GPT-4), 32k (GPT-3.5)',
contextEditSave: 'Save',
contextEditCancel: 'Cancel',
contextEditInvalid: 'Please enter a valid context length',
contextEditSuccess: 'Context length updated',
contextEditFailed: 'Update failed',
emptyState: 'Start a conversation with Hermes Agent',
2026-05-14 09:03:57 +08:00
cliEmptyState: 'Start a CLI chat session',
2026-05-19 08:25:01 +08:00
outlineTitle: 'Conversation Outline',
outlineEmpty: 'No conversation content',
outlineUserQuestion: 'User question',
inputPlaceholder: 'Type a message... (Enter to send, Shift+Enter for new line)',
2026-05-15 12:04:03 +08:00
slashCommandArgs: {
message: '<message>',
title: '<title>',
text: '<text>',
},
slashCommands: {
usage: 'Calculate current session usage',
status: 'Show session status and queue',
abort: 'Stop the active bridge run',
queue: 'Queue a message behind the active run',
clear: 'Clear the current display',
clearHistory: 'Delete this sessions stored message history',
title: 'Rename this session',
compress: 'Run context compression while idle',
steer: 'Send steering text to the active bridge run',
destroy: 'Release the bridge agent for this session',
},
attachFiles: 'Attach files',
autoPlaySpeech: 'Auto-play voice',
2026-05-17 09:01:59 +08:00
showToolCalls: 'Show tool calls',
hideToolCalls: 'Hide tool calls',
messageQueue: 'Message queue',
removeQueuedMessage: 'Remove queued message',
stop: 'Stop',
start: 'Start',
stopGateway: 'Stop Gateway',
send: 'Send',
contextUsed: 'Context used:',
sessions: 'Sessions',
webUiSessions: 'Sessions',
allProfiles: 'All profiles',
profileMissingModelsTip: 'Profile "{profile}" has no available provider or model for this session',
sessionScopeHint: 'Chat shows Web UI/API Server sessions only. CLI, Telegram, Discord, Cron, and other channel sessions are read-only in History.',
openHistory: 'Open History',
hermesHistory: 'Hermes History',
historyScopeHint: 'Read-only Hermes history sessions for the current profile, grouped by source.',
noSessions: 'No sessions',
2026-04-22 14:00:34 +08:00
searchTitle: 'Search Sessions',
searchSubtitle: 'Search by title or message content',
2026-05-16 02:29:51 +02:00
searchScope: 'Search scope: Web UI local session database only. Read-only Hermes history sessions are not included.',
2026-04-22 14:00:34 +08:00
searchHint: 'Cmd/Ctrl+K',
searchPlaceholder: 'Search sessions...',
searchEmpty: 'Recent sessions',
searchRecent: 'Recent session',
searchNoResults: 'No sessions match your search',
searchNoSnippet: 'No snippet available',
searchEnterHint: 'Enter to open · Esc to close',
searchFailed: 'Failed to search sessions',
newChat: 'New Chat',
2026-05-16 00:11:51 +08:00
approvalKicker: 'Terminal permission',
approvalTitle: 'Review command before running',
approvalAllowOnce: 'Allow once',
approvalAllowSession: 'Allow session',
approvalAlways: 'Always',
approvalDeny: 'Deny',
2026-05-14 09:03:57 +08:00
newCliChat: 'New CLI',
deleteSession: 'Delete this session?',
sessionDeleted: 'Session deleted',
toggleBatchMode: 'Batch selection',
selectAll: 'Select all',
confirmBatchDelete: 'Delete {count} selected sessions?',
batchDeleteSuccess: 'Deleted {count} sessions',
batchDeletePartial: '{failed} sessions failed to delete',
batchDeleteFailed: 'Batch delete failed',
rename: 'Rename',
pin: 'Pin',
unpin: 'Unpin',
pinned: 'Pinned',
chatMode: 'Chat',
liveMode: 'Live',
liveSessions: 'Live Sessions',
recentBadge: 'Recent',
linkedSessions: '{count} linked',
noVisibleMessages: 'No human-visible messages.',
monitorRoleUser: 'User',
monitorRoleAssistant: 'Assistant',
copySessionId: 'Copy Session ID',
export: 'Export',
exportFull: 'Full Export (JSON)',
exportCompressed: 'Compressed Export (TXT)',
exportCompressing: 'Compressing context, please wait...',
exportSuccess: 'Session exported',
exportFailed: 'Export failed',
renamed: 'Renamed',
renameFailed: 'Rename failed',
renameSession: 'Rename Session',
2026-05-03 22:10:40 +08:00
sessionNotFound: 'Session not found',
enterNewTitle: 'Enter new title',
workspace: 'Workspace',
setWorkspace: 'Set Workspace',
setWorkspaceTitle: 'Set Session Workspace',
workspacePlaceholder: 'Enter project path, e.g. /home/user/project',
workspaceSet: 'Workspace set',
workspaceSetFailed: 'Failed to set workspace',
setModel: 'Set Model',
setModelTitle: 'Set Session Model',
modelSet: 'Model set',
modelSetFailed: 'Failed to set model',
other: 'Other',
runFailed: 'Run failed',
error: 'Error',
tool: 'Tool',
arguments: 'Arguments',
result: 'Result',
truncated: '... (truncated)',
executionDuration: 'Execution time',
thinkingLabel: 'Thinking',
thinkingInProgress: 'Thinking…',
thinkingShow: 'Show thinking',
thinkingHide: 'Hide thinking',
thinkingDuration: 'Observed {duration}',
thinkingChars: '{count} chars',
copyBubble: 'Copy message',
copiedBubble: 'Message copied',
copyFailed: 'Copy failed',
playSpeech: 'Play voice',
pauseSpeech: 'Pause',
resumeSpeech: 'Resume',
stopSpeech: 'Stop',
speechNotSupported: 'Voice playback not supported in this browser',
},
2026-05-08 11:32:47 +08:00
// Kanban
kanban: {
title: 'Kanban Board',
createTask: 'New Task',
noTasks: 'No tasks',
allStatuses: 'All Statuses',
allAssignees: 'All Assignees',
board: {
create: 'New Board',
archive: 'Archive Board',
slugPlaceholder: 'Board slug, e.g. project-a',
namePlaceholder: 'Display name (optional)',
slugRequired: 'Board slug is required',
created: 'Board created',
archived: 'Board archived',
archiveConfirm: 'Archive the current board?',
},
2026-05-08 11:32:47 +08:00
columns: {
triage: 'Triage',
todo: 'To Do',
ready: 'Ready',
running: 'Running',
blocked: 'Blocked',
done: 'Done',
archived: 'Archived',
},
form: {
title: 'Title',
titlePlaceholder: 'Task title',
titleRequired: 'Title is required',
body: 'Description',
bodyPlaceholder: 'Task description (optional)',
assignee: 'Assignee',
selectAssignee: 'Select assignee...',
priority: 'Priority',
selectPriority: 'Select priority...',
},
card: {
assigneeTooltip: 'Assignee',
priority: {
low: 'Low',
medium: 'Medium',
high: 'High',
},
timeAgo: {
justNow: 'just now',
minutes: '{count}m ago',
hours: '{count}h ago',
days: '{count}d ago',
},
},
detail: {
status: 'Status',
assignee: 'Assignee',
priority: 'Priority',
tenant: 'Tenant',
createdAt: 'Created',
startedAt: 'Started',
completedAt: 'Completed',
comments: 'Comments',
events: 'Events',
runs: 'Runs',
result: 'Result',
sessions: 'Related Sessions',
sessionMessages: 'Session Messages',
noSessions: 'No related sessions found.',
artifacts: 'Artifacts',
sources: 'Sources',
highlights: 'Highlights',
},
action: {
title: 'Actions',
complete: 'Complete',
completeSummary: 'Completion summary (optional)',
block: 'Block',
blockReason: 'Reason for blocking',
unblock: 'Unblock',
assign: 'Assign',
assignTo: 'Assign to...',
},
message: {
taskCreated: 'Task created',
taskCompleted: 'Task completed',
taskBlocked: 'Task blocked',
taskUnblocked: 'Task unblocked',
taskAssigned: 'Task assigned',
loadFailed: 'Failed to load task',
},
stats: {
total: 'Total',
tasks: 'Tasks',
2026-05-08 11:32:47 +08:00
},
},
// Jobs
jobs: {
title: 'Scheduled Jobs',
createJob: 'Create Job',
editJob: 'Edit Job',
noJobs: 'No scheduled jobs yet. Create one to get started.',
name: 'Name',
namePlaceholder: 'Job name',
schedule: 'Schedule (Cron Expression)',
schedulePlaceholder: 'e.g. 0 9 * * *',
quickPresets: 'Quick Presets',
selectPreset: 'Select a preset...',
presetEveryMinute: 'Every minute',
presetEvery5Min: 'Every 5 minutes',
presetEveryHour: 'Every hour',
presetEveryDay: 'Every day at 00:00',
presetEveryDay9: 'Every day at 09:00',
presetEveryMonday: 'Every Monday at 09:00',
presetEveryMonth: 'Every month 1st at 09:00',
prompt: 'Prompt',
promptPlaceholder: 'The prompt to execute',
deliverTarget: 'Deliver Target',
origin: 'Origin',
local: 'Local',
repeatCount: 'Repeat Count (optional)',
modelPlaceholder: 'Default model',
repeatPlaceholder: 'Leave empty for infinite',
jobCreated: 'Job created',
jobUpdated: 'Job updated',
nameRequired: 'Name is required',
scheduleRequired: 'Schedule is required',
loadFailed: 'Failed to load job',
jobPaused: 'Job paused',
jobResumed: 'Job resumed',
jobTriggered: 'Job triggered',
modelUpdated: 'Model updated',
jobDeleted: 'Job deleted',
status: {
running: 'Running',
paused: 'Paused',
disabled: 'Disabled',
scheduled: 'Scheduled',
},
info: {
model: 'Model',
schedule: 'Schedule',
lastRun: 'Last Run',
nextRun: 'Next Run',
deliver: 'Deliver',
repeat: 'Repeat',
},
action: {
pause: 'Pause',
pauseJob: 'Pause job',
resume: 'Resume',
resumeJob: 'Resume job',
runNow: 'Run Now',
triggerImmediately: 'Trigger immediately',
},
runHistory: {
title: 'Run History',
runs: 'runs',
noRuns: 'No run history found.',
},
},
// Skills
skills: {
title: 'Skills',
searchPlaceholder: 'Search skills...',
noMatch: 'No skills match your search',
noSkills: 'No skills found',
backTo: 'Back to',
attachedFiles: 'Attached Files',
loadFailed: 'Failed to load skill',
fileLoadFailed: 'Failed to load file',
modified: 'Modified',
archived: 'Archived',
pinned: 'Pinned',
pin: 'Pin skill',
unpin: 'Unpin skill',
pinFailed: 'Failed to change pin status',
toggleFailed: 'Failed to toggle skill',
source: {
builtin: 'Builtin',
hub: 'Hub',
local: 'Local',
},
},
2026-05-10 13:50:39 +02:00
// Plugins
plugins: {
title: 'Plugins',
refresh: 'Refresh',
notice: 'Read-only inventory of discoverable Hermes plugin manifests. Discovery metadata is read without loading plugin code. Management actions stay in CLI for v1; changes take effect in new Hermes sessions.',
loadFailed: 'Failed to load plugins',
commandCopied: 'Command copied',
searchPlaceholder: 'Search key, name, description, path...',
source: 'Source',
kind: 'Kind',
statusTitle: 'Status',
configStatus: 'config: {status}',
notAvailable: 'n/a',
copyCommand: 'Copy command',
managedElsewhere: 'managed elsewhere',
noMatch: 'No plugins match the current filters',
enabled: 'enabled',
disabled: 'disabled',
summary: {
total: 'Total',
active: 'Enabled / auto',
inactive: 'Inactive',
disabled: 'Disabled',
providerManaged: 'Provider-managed',
},
status: {
enabled: 'Enabled',
'auto-active': 'Auto-active',
inactive: 'Inactive',
disabled: 'Disabled',
'provider-managed': 'Provider-managed',
},
statusLabel: {
enabled: 'Enabled by config',
'auto-active': 'Auto-active',
inactive: 'Inactive',
disabled: 'Disabled',
'provider-managed': 'Provider-managed',
},
configStatuses: {
enabled: 'enabled',
disabled: 'disabled',
'not-enabled': 'not enabled',
auto: 'auto',
'provider-managed': 'provider-managed',
},
table: {
plugin: 'Plugin',
status: 'Status',
source: 'Source',
kind: 'Kind',
capabilities: 'Capabilities',
path: 'Path / entrypoint',
cli: 'CLI',
},
capabilities: {
tools: '{count} tools',
hooks: '{count} hooks',
env: '{count} env',
},
metadata: {
agentRoot: 'Agent root',
python: 'Python',
scanCwd: 'Scan cwd',
projectPlugins: 'Project plugins',
},
},
// Memory
memory: {
title: 'Memory',
refresh: 'Refresh',
loadFailed: 'Failed to load memory',
myNotes: 'My Notes',
noNotes: 'No notes yet.',
notesPlaceholder: 'Write your notes...',
userProfile: 'User Profile',
noProfile: 'No profile yet.',
profilePlaceholder: 'Write your profile...',
soul: 'Soul',
noSoul: 'No soul configuration yet.',
soulPlaceholder: 'Write soul configuration...',
},
// Models
models: {
title: 'Models',
searchPlaceholder: 'Search models...',
addProvider: 'Add Provider',
providerType: 'Provider Type',
preset: 'Preset',
custom: 'Custom',
selectProvider: 'Select Provider',
chooseProvider: 'Choose a provider...',
getApiKey: 'Get API Key',
name: 'Name',
autoGeneratedName: 'Auto-generated from Base URL',
baseUrl: 'Base URL',
region: 'Region',
regionIntl: 'International',
regionCn: 'Mainland China',
baseUrlPlaceholder: 'e.g. https://api.example.com/v1',
apiKey: 'API Key',
apiKeyPlaceholder: 'sk-...',
defaultModel: 'Default Model',
selectOrInput: 'Select or type a model name...',
selectModel: 'Select a model...',
providerAdded: 'Provider added',
providerDeleted: 'Provider deleted',
deleteProvider: 'Delete Provider',
deleteConfirm: 'Are you sure you want to delete "{name}"?',
codexLoginTitle: 'OpenAI Codex Login',
codexWaiting: 'Enter this code at the authorization page to complete login:',
codexCopyCode: 'Code copied',
codexOpenLink: 'Open authorization page',
codexApproved: 'Login successful',
codexExpired: 'Authorization expired. Please try again.',
nousLoginTitle: 'Nous Portal Login',
nousWaiting: 'Enter this code at the authorization page to complete login:',
nousCopyCode: 'Code copied',
nousOpenLink: 'Open authorization page',
nousApproved: 'Login successful',
nousDenied: 'Authorization was denied. Please try again.',
nousExpired: 'Authorization expired. Please try again.',
copilotLoginTitle: 'GitHub Copilot Login',
copilotWaiting: 'Open GitHub and enter the device code below to authorize. The window will close automatically once approved.',
copilotCopyCode: 'Code copied',
copilotOpenLink: 'Open GitHub authorization page',
copilotApproved: 'Sign-in succeeded!',
copilotDenied: 'Authorization denied.',
copilotExpired: 'The authorization link has expired. Please retry.',
copilotAddDetectedTitle: 'GitHub Copilot detected',
copilotAddDetected: 'A GitHub Copilot OAuth token was detected on this machine. Click Add to enable Copilot in Hermes.',
copilotAddSourceEnv: 'Source: ~/.hermes/.env (COPILOT_GITHUB_TOKEN)',
copilotAddSourceGhCli: 'Source: gh CLI (gh auth token)',
copilotAddSourceAppsJson: 'Source: VS Code Copilot extension (apps.json)',
copilotDeleteHintEnv: 'This will clear COPILOT_GITHUB_TOKEN in ~/.hermes/.env. Other tools are not affected.',
copilotDeleteHintGhCli: 'Copilot will be hidden from Hermes. Your gh CLI login is not affected — `gh auth status` will still show you signed in.',
copilotDeleteHintAppsJson: 'Copilot will be hidden from Hermes. Your VS Code Copilot extension login is not affected.',
xaiLoginTitle: 'xAI Grok OAuth Login',
xaiWaiting: 'Complete authorization in the opened xAI page. This window will close automatically once approved.',
xaiOpenLink: 'Open xAI authorization page',
xaiCopyLink: 'Copy authorization link',
xaiApproved: 'Sign-in succeeded!',
xaiExpired: 'The authorization link has expired. Please retry.',
customBadge: 'CUSTOM',
previewBadge: 'PREVIEW',
disabledBadge: 'UNAVAILABLE',
disabledTooltip: "This model is currently unavailable for your account.",
customModelPlaceholder: 'Unlisted model ID',
customModelHint: 'For provider-supported models not returned by the API; not a display rename. Press Enter to load.',
removeCustomModel: 'Remove this unlisted model',
noProviders: 'No providers found. Add a custom provider to get started.',
models: 'Models',
count: 'models',
more: 'more',
aliasEdit: 'Rename',
aliasTitle: 'Model display name',
aliasTitleFor: 'Display name for {model}',
aliasPlaceholder: 'Leave empty to use original model ID',
aliasHint: 'Display-only alias. Hermes still receives the canonical model ID.',
aliasCanonical: 'Original ID: {model}',
aliasUseOriginal: 'Use original ID',
aliasManage: 'Display names',
aliasManageFor: 'Display names for {provider}',
aliasSaveFailed: 'Failed to save display name',
manageVisibleModels: 'Manage visible models',
manageVisibleModelsFor: 'Manage visible models for {name}',
visibilityHint: 'Only affects the Web UI model picker and Models page. Hermes CLI provider/model config is not rewritten; calls still use canonical model IDs.',
visibilitySelectOne: 'Keep at least one visible model',
visibilitySaved: 'Visible models saved',
visibilitySaveFailed: 'Failed to save visible models',
showAllModels: 'Show all models',
clearVisibleModels: 'Clear selection',
currentDefault: 'Current default',
defaultShort: 'Default',
builtIn: 'Built-in',
customType: 'Custom',
provider: 'Provider',
contextLength: 'Context Length',
contextLengthPlaceholder: 'e.g. 200000 (optional)',
local: 'Local ({host})',
selectProviderRequired: 'Please select a provider',
baseUrlRequired: 'Base URL is required',
apiKeyRequired: 'API Key is required',
modelRequired: 'Default Model is required',
enterBaseUrl: 'Please enter Base URL first',
unexpectedFormat: 'Unexpected response format',
foundModels: 'Found {count} models',
fetchFailed: 'Failed to fetch models',
},
// Profiles
gateways: {
title: 'Gateways',
running: 'Running',
stopped: 'Stopped',
started: 'Started',
startFailed: 'Failed to start gateway',
stopFailed: 'Failed to stop gateway',
},
profiles: {
title: 'Profiles',
create: 'Create Profile',
import: 'Import',
export: 'Export',
rename: 'Rename',
delete: 'Delete',
switchTo: 'Switch to',
switchConfirm: 'Switching to profile "{name}" will restart the gateway. Continue?',
switchSuccess: 'Switched to profile "{name}"',
switchFailed: 'Failed to switch profile. Gateway may need manual restart.',
createSuccess: 'Profile "{name}" created',
createFailed: 'Failed to create profile',
renameSuccess: 'Profile renamed',
renameFailed: 'Failed to rename profile',
deleteConfirm: 'Are you sure you want to delete profile "{name}"?',
deleteSuccess: 'Profile deleted',
deleteFailed: 'Failed to delete profile',
exportSuccess: 'Profile exported',
exportFailed: 'Failed to export profile',
importSuccess: 'Profile imported',
importFailed: 'Failed to import profile',
importSelectFile: 'Select archive file',
importInvalidFile: 'Please select a valid archive (.tar.gz, .tgz, .gz, .zip)',
name: 'Profile Name',
namePlaceholder: 'Lowercase letters, numbers, hyphens only',
2026-05-03 22:10:40 +08:00
nameValidation: 'Profile name can only contain lowercase letters, numbers, underscores, and hyphens',
newName: 'New Name',
newNamePlaceholder: 'Lowercase letters, numbers, hyphens',
cloneFromCurrent: 'Clone from current profile',
cloneCleanupNotice: 'Cloning automatically skips exclusive platform credentials (Weixin / Telegram / Slack, etc.) to avoid conflicts with the source profile',
cloneStrippedCredentials: 'Stripped {count} exclusive credential(s): {list}',
cloneDisabledPlatforms: 'Disabled {count} platform(s): {list}',
cloneStrippedConfigCredentials: 'Stripped {count} embedded credential(s) from config.yaml: {list}',
archivePath: 'Archive Path',
archivePathPlaceholder: 'Server path to archive file',
importName: 'Profile Name (optional)',
importNamePlaceholder: 'Leave empty to use archive name',
active: 'Active',
model: 'Model',
gateway: 'Gateway',
alias: 'Alias',
provider: 'Provider',
path: 'Path',
skills: 'Skills',
hasEnv: 'Has .env',
hasSoulMd: 'Has soul.md',
noProfiles: 'No profiles found. Create one to get started.',
avatar: {
title: 'Custom Avatar',
customize: 'Avatar',
upload: 'Upload Image',
random: 'Randomize',
reset: 'Use Default',
hint: 'PNG, JPEG, or WebP. Max 1MB.',
invalidType: 'Please choose a PNG, JPEG, or WebP image',
tooLarge: 'Avatar image must be 1MB or smaller',
saveSuccess: 'Avatar saved',
saveFailed: 'Failed to save avatar',
resetSuccess: 'Default avatar restored',
resetFailed: 'Failed to restore default avatar',
},
2026-05-20 12:59:34 +08:00
runtime: {
activeProfile: 'Active: {name}',
bridgeWorker: 'Bridge worker',
gateway: 'Gateway',
active: 'Active',
activeTag: 'Active',
idle: 'Idle',
running: 'Running',
stopped: 'Stopped',
restartGateway: 'Restart Gateway',
restartProfile: 'Restart Profile',
switchProfile: 'Switch Profile',
gatewayRestarted: 'Gateway restarted: {name}',
gatewayRestartFailed: 'Failed to restart gateway',
profileRestarted: 'Profile restarted: {name}',
profileRestartFailed: 'Failed to restart profile',
},
},
// Logs
logs: {
title: 'Logs',
all: 'All',
searchPlaceholder: 'Search...',
refresh: 'Refresh',
noEntries: 'No log entries',
},
// Settings
settings: {
title: 'Settings',
saved: 'Saved',
saveFailed: 'Save failed',
tabs: {
display: 'Display',
account: 'Account',
agent: 'Agent',
memory: 'Memory',
compression: 'Compression',
session: 'Session',
privacy: 'Privacy',
apiServer: 'API Server',
models: 'Models',
voice: 'Voice',
},
models: {
apiKey: 'API Key',
apiKeyPlaceholder: 'Enter API key',
save: 'Save',
saved: 'Saved',
saveFailed: 'Save failed',
noProviders: 'No providers configured',
},
display: {
streaming: 'Stream Responses',
streamingHint: 'Show AI replies in real-time',
compact: 'Compact Mode',
compactHint: 'Reduce message spacing',
showReasoning: 'Show Reasoning',
showReasoningHint: 'Show model thinking process',
showCost: 'Show Cost',
showCostHint: 'Show token usage in replies',
inlineDiffs: 'Inline Diffs',
inlineDiffsHint: 'Show code changes inline',
bellOnComplete: 'Completion Sound',
bellOnCompleteHint: 'Play sound when AI finishes',
busyInputMode: 'Busy Input Mode',
busyInputModeHint: 'Allow input while AI is processing',
theme: 'Theme',
themeHint: 'Choose light, dark, or follow system preference',
themeLight: 'Light',
themeDark: 'Dark',
themeSystem: 'System',
},
agent: {
maxTurns: 'Max Turns',
maxTurnsHint: 'Maximum interaction rounds per conversation',
gatewayTimeout: 'Gateway Timeout',
gatewayTimeoutHint: 'Request timeout in seconds',
restartDrainTimeout: 'Restart Drain Timeout',
restartDrainTimeoutHint: 'Drain timeout before restart in seconds',
toolEnforcement: 'Tool Enforcement',
toolEnforcementHint: 'Control tool call execution mode',
auto: 'Auto',
always: 'Always',
never: 'Never',
},
memory: {
enabled: 'Enable Memory',
enabledHint: 'Allow AI to remember conversation context',
userProfile: 'User Profile',
userProfileHint: 'Allow AI to remember user preferences',
charLimit: 'Memory Char Limit',
charLimitHint: 'Max characters for MEMORY.md',
userCharLimit: 'User Profile Char Limit',
userCharLimitHint: 'Max characters for USER.md',
},
compression: {
enabled: 'Enable Compression',
enabledHint: 'Automatically compress long chat history before it exceeds the model context',
threshold: 'Compression Threshold',
thresholdHint: 'Start compression when estimated tokens exceed this context ratio',
targetRatio: 'Target Ratio',
targetRatioHint: 'Target history size after compression as a context ratio',
protectLastN: 'Protect Recent Messages',
protectLastNHint: 'Keep this many latest messages uncompressed',
protectFirstN: 'Protect First Messages',
protectFirstNHint: 'Keep this many earliest messages uncompressed',
},
session: {
mode: 'Reset Mode',
modeHint: 'Trigger condition for session reset',
modeBoth: 'Idle + Scheduled',
modeIdle: 'Idle Only',
modeDaily: 'Scheduled Only',
modeNone: 'Never (Manual Only)',
idleMinutes: 'Idle Timeout',
idleMinutesHint: 'Wait time before auto-reset (minutes)',
atHour: 'Scheduled Reset Time',
humanOnly: 'Show human sessions only',
humanOnlyHint: 'Hide sub-agent/session monitor noise by default',
liveMonitorHumanOnly: 'Live monitor: show human sessions only',
liveMonitorHumanOnlyHint: 'Hide sub-agent/session monitor noise in the Live monitor by default',
atHourHint: 'Reset session at this hour daily',
requireAuth: 'Session Authorization',
requireAuthHint: 'Require authorization for session operations',
},
privacy: {
redactPii: 'Redact PII',
redactPiiHint: 'Auto-detect and hide sensitive info (passwords, keys, etc.)',
},
apiServer: {
enable: 'Enable',
enableHint: 'Enable API server',
host: 'Host',
hostHint: 'Listen address',
port: 'Port',
portHint: 'Listen port',
key: 'Key',
keyHint: 'API access key',
cors: 'CORS Origins',
corsHint: 'Allowed cross-origin sources',
},
lockedIps: {
title: 'Locked IPs',
count: '{count} locked',
empty: 'No locked IPs',
unlock: 'Unlock',
unlockAll: 'Unlock All',
unlockAllConfirm: 'Unlock all locked IPs?',
unlocked: 'IP unlocked',
allUnlocked: '{count} IPs unlocked',
},
voice: {
ttsProvider: 'TTS Provider',
ttsProviderHint: 'Choose the text-to-speech engine for message playback',
providerWebSpeech: 'WebSpeech API (Browser)',
providerOpenai: 'OpenAI TTS',
providerCustom: 'Custom Endpoint (OpenAI-compatible)',
providerEdge: 'Edge TTS (Free, no API Key)',
// WebSpeech
webspeechVoice: 'Voice',
webspeechVoiceHint: 'Select a voice from your browser or OS',
webspeechVoicePlaceholder: 'Auto (default voice)',
// OpenAI
openaiKey: 'API Key',
openaiKeyHint: 'Your OpenAI API key with TTS access',
openaiUrl: 'API Base URL',
openaiUrlHint: 'e.g. https://api.openai.com/v1/audio/speech',
openaiModel: 'Model',
openaiModelHint: 'tts-1 (faster) / tts-1-hd (higher quality)',
openaiVoice: 'Voice',
openaiVoiceHint: 'Voice to use for synthesis',
// Custom endpoint
customHint: 'Use any OpenAI-compatible TTS API — works with GPT-SoVITS, CosyVoice, etc.',
customUrl: 'API URL',
customUrlHint: 'Base URL of your TTS service',
customUrlPlaceholder: 'The address configured in the local adapter, e.g. http://127.0.0.1:9880',
customApiKey: 'API Key (Optional)',
customApiKeyHint: 'Some custom endpoints require authentication',
customApiKeyPlaceholder: 'Leave blank if not needed',
// Edge TTS
edgeHint: 'Powered by Microsoft Edge TTS (node-edge-tts).',
edgeUrl: 'Adapter URL',
edgeUrlHint: 'Address of your Edge TTS adapter, e.g. http://127.0.0.1:9882',
edgeUrlPlaceholder: 'http://127.0.0.1:9882',
edgeVoice: 'Voice',
edgeVoiceHint: 'Select a voice for speech synthesis',
edgeRate: 'Speed',
edgeRateHint: 'Adjust speech speed (0.5x ~ 2.0x)',
edgePitch: 'Pitch',
edgePitchHint: 'Adjust speech pitch (-20 ~ +20 Hz)',
// Test
testTitle: 'Test Voice',
testText: 'Test Text',
testTextPlaceholder: 'Enter text to test...',
testTextDefault: 'Hello, this is a voice test.',
testButton: 'Test',
testButtonPlaying: 'Playing...',
testFailed: 'Test failed: {error}',
// MiMo TTS
providerMimo: 'MiMo TTS',
mimoHint: 'Xiaomi MiMo TTS — supports preset voices, voice design, and voice clone modes',
mimoApiKey: 'API Key',
mimoApiKeyHint: 'Get your key at platform.xiaomimimo.com',
mimoApiKeyPlaceholder: 'MiMo API Key',
mimoBaseUrl: 'Base URL',
mimoBaseUrlHint: 'MiMo API endpoint URL',
mimoModel: 'Model',
mimoModelHint: 'Select speech synthesis model',
mimoModelPreset: 'Preset Voices',
mimoModelVoiceDesign: 'Voice Design',
mimoModelVoiceClone: 'Voice Clone',
mimoVoice: 'Voice',
mimoVoiceHint: 'Select a preset voice',
mimoVoiceDesignPrompt: 'Voice Description',
mimoVoiceDesignPromptHint: 'Describe the voice characteristics you want',
mimoVoiceDesignPromptPlaceholder: 'e.g., A warm young female voice, slightly slow, with a magnetic tone',
mimoCloneAudio: 'Upload Audio',
mimoCloneAudioHint: 'Upload an audio sample for voice cloning (mp3/wav, max 10MB)',
mimoCloneAudioUpload: 'Choose File',
mimoCloneAudioClear: 'Clear',
mimoStylePrompt: 'Style Prompt',
mimoStylePromptHint: 'Optional — describe the speaking style in natural language',
mimoStylePromptPlaceholder: 'e.g., Bright and bouncy tone, fast pace',
},
},
// Platform channel settings
platform: {
requireMention: "Require {'@'}Mention",
requireMentionGroup: "Require {'@'}mention in groups to respond",
requireMentionChannel: "Require {'@'}mention in channels to respond",
requireMentionRoom: "Require {'@'}mention in rooms to respond",
reactions: 'Reactions',
reactionsHint: 'React to messages with emoji',
freeResponseChats: 'Free Response Chats',
freeResponseChatsHint: "Chat IDs that respond without {'@'}mention (comma-separated)",
freeResponseChannels: 'Free Response Channels',
freeResponseChannelsHint: "Channel IDs that respond without {'@'}mention (comma-separated)",
freeResponseRooms: 'Free Response Rooms',
freeResponseRoomsHint: "Room IDs that respond without {'@'}mention (comma-separated)",
mentionPatterns: 'Custom Mention Patterns',
mentionPatternsHint: 'Additional trigger patterns',
autoThread: 'Auto Thread',
autoThreadHint: "Auto-create reply threads after {'@'}mention",
autoThreadHintRoom: 'Auto-create reply threads in rooms',
dmMentionThreads: 'DM Mention Threads',
dmMentionThreadsHint: 'Use thread replies for mentions in DMs',
allowBots: 'Allow Bot Messages',
allowBotsHint: 'Respond to messages from other bots',
allowedChannels: 'Allowed Channels',
allowedChannelsHint: 'Whitelist channel IDs (comma-separated)',
ignoredChannels: 'Ignored Channels',
ignoredChannelsHint: 'Channels where bot never responds (comma-separated)',
noThreadChannels: 'No-Thread Channels',
noThreadChannelsHint: 'Channels where bot responds without threads (comma-separated)',
exclusiveTokenWarning: 'This platform uses exclusive token locking. Each profile must use a different identity token to avoid conflicts with other profiles.',
botToken: 'Bot Token',
botTokenHint: 'Bot token from developer portal',
accessToken: 'Access Token',
accessTokenHint: 'Matrix access token',
homeserver: 'Homeserver URL',
homeserverHint: 'Matrix homeserver URL',
appId: 'App ID',
appIdHint: 'Feishu App ID',
appSecret: 'App Secret',
appSecretHint: 'Feishu App Secret',
clientId: 'Client ID',
clientIdHint: 'DingTalk Client ID',
clientSecret: 'Client Secret',
clientSecretHint: 'DingTalk Client Secret',
allowedUsers: 'Allowed Users',
allowedUsersHint: 'Whitelist user IDs or OpenIDs (comma-separated)',
allowAllUsers: 'Allow All Users',
allowAllUsersHint: 'Allow messages from any user; keep off to use the allowlist',
botId: 'Bot ID',
botIdHint: 'WeCom Bot ID',
wecomSecretHint: 'WeCom Bot Secret',
waEnabled: 'Enable WhatsApp',
waEnabledHint: 'Enable WhatsApp via QR code pairing',
weixinToken: 'Weixin Token',
weixinTokenHint: 'From weixin CLI QR login (hermes weixin)',
accountId: 'Account ID',
accountIdHint: 'Weixin account ID',
qrLogin: 'QR Login',
qrRelogin: 'Re-login',
qrFetching: 'Fetching QR code...',
qrScanHint: 'Scan with WeChat to login',
qrScanedHint: 'Scaned, please confirm on phone...',
// QQ
qqAppId: 'App ID',
qqAppIdHint: 'QQ Open Platform Bot App ID',
qqAppSecret: 'App Secret',
qqAppSecretHint: 'QQ Open Platform Bot App Secret',
qqMarkdown: 'Markdown Support',
qqMarkdownHint: 'Enable Markdown formatted messages (some clients may not support)',
qqSandbox: 'Sandbox Mode',
qqSandboxHint: 'Enable sandbox environment (for testing)',
qqQrScanHint: 'Scan the QR code with QQ, or open the link on your phone to complete binding',
},
// Language
language: {
label: 'Language',
zh: '中文',
en: 'English',
},
// Terminal
terminal: {
sessions: 'Sessions',
newTab: 'New Terminal',
closeSession: 'Close this session?',
sessionExited: 'Exited',
processExited: 'Process exited with code {code}',
2026-05-03 22:10:40 +08:00
noSessions: 'No terminal sessions',
connectionFailed: 'Terminal service connection failed',
connectionClosed: 'Terminal connection closed',
connectionError: 'Terminal connection error',
},
// Group Chat
groupChat: {
title: 'Group Chat',
createRoom: 'Create Room',
joinByCode: 'Join by Code',
roomName: 'Room Name',
roomNamePlaceholder: 'Enter room name',
inviteCode: 'Invite Code',
autoGenerate: 'Auto-generate',
noRooms: 'No rooms yet',
selectOrCreate: 'Select or create a room to start chatting',
agents: 'Agents',
addAgent: 'Add Agent',
selectProfile: 'Select a profile',
agentAdded: 'Agent added',
agentAlreadyInRoom: 'Agent already in this room',
agentAddFailedCount: '{count} agent(s) were not added: {details}',
noAgents: 'No agents in this room',
members: 'members',
roomCreated: 'Room created',
roomDeleted: 'Room deleted',
roomCloned: 'Room cloned',
cloneRoom: 'Clone room',
deleteRoomConfirm: 'Delete this room?',
clearContext: 'Clear context',
clearContextConfirm: 'Clear this room context? Messages and compression snapshots will be removed, but agents and members stay.',
contextCleared: 'Context cleared',
you: 'You',
joined: 'Joined room',
joinFailed: 'Failed to join room',
inputPlaceholder: 'Type a message... (Enter to send)',
enterCode: 'Enter invite code',
yourName: 'Your Name',
yourNamePlaceholder: 'Enter your display name',
yourDescription: 'Description (optional)',
yourDescriptionPlaceholder: 'Tell others who you are...',
agentName: 'Agent Name',
agentNamePlaceholder: 'Custom name (leave empty to use profile name)',
agentDesc: 'Agent Description',
agentDescPlaceholder: 'Describe what this agent does...',
agentReplying: 'is replying...',
agentCompressing: 'is compressing context...',
compressionSettings: 'Compression Settings',
triggerTokens: 'Trigger Tokens',
triggerTokensDesc: 'Token threshold to trigger context compression',
maxHistoryTokens: 'Max History Tokens',
maxHistoryTokensDesc: 'Maximum tokens for compressed context sent to LLM',
tailMessageCount: 'Tail Message Count',
tailMessageCountDesc: 'Number of recent messages to keep verbatim after compression',
compressionConfig: 'Compression Config',
compressionSaved: 'Compression config saved',
compressNow: 'Compress Now',
compressingInProgress: 'Compression in progress, please wait',
},
// Usage
usage: {
title: 'Usage Statistics',
refresh: 'Refresh',
totalTokens: 'Total Tokens',
inputTokens: 'Input',
outputTokens: 'Output',
totalSessions: 'Total Sessions',
avgPerDay: '~{n}/day avg',
estimatedCost: 'Est. Cost',
cacheHitRate: 'Cache Hit Rate',
modelBreakdown: 'Model Breakdown',
dailyTrend: 'Daily Usage',
date: 'Date',
tokens: 'Tokens',
cache: 'Cache',
cacheRead: 'Cache Read',
cacheWrite: 'Cache Write',
sessions: 'Sessions',
cost: 'Cost',
noData: 'No usage data',
},
skillsUsage: {
title: 'Skills Usage',
subtitle: 'Track skill loads and edits from Hermes sessions',
refresh: 'Refresh',
periodSelector: 'Skill usage period',
periodLabel: '{days}d',
summary: 'Summary',
totalActions: 'Actions',
loads: 'Loads',
edits: 'Edits',
distinctSkills: 'Skills',
topSkills: 'Top Skills',
dailyTrend: 'Daily Trend',
periodSummary: 'Last {days} days',
skill: 'Skill',
share: 'Share',
lastUsed: 'Last Used',
noData: 'No skill usage data',
loadFailed: 'Failed to load skill usage',
otherSkills: 'Other skills',
},
// Files
files: {
title: 'Files',
2026-05-03 22:10:40 +08:00
fileTree: 'File Tree',
tree: 'Directory Tree',
list: 'File List',
breadcrumbRoot: 'Home',
newFile: 'New File',
newFolder: 'New Folder',
upload: 'Upload',
refresh: 'Refresh',
open: 'Open',
edit: 'Edit',
preview: 'Preview',
download: 'Download',
copyPath: 'Copy Path',
rename: 'Rename',
delete: 'Delete',
name: 'Name',
size: 'Size',
modified: 'Modified',
actions: 'Actions',
emptyDir: 'Empty directory',
loading: 'Loading...',
confirmDelete: 'Are you sure you want to delete "{name}"?',
confirmDeleteDir: 'Are you sure you want to delete directory "{name}" and all its contents?',
deleteFailed: 'Delete failed',
deleted: 'Deleted',
renameTo: 'Rename to',
newFileName: 'File name',
newFolderName: 'Folder name',
created: 'Created',
createFailed: 'Create failed',
renamed: 'Renamed',
renameFailed: 'Rename failed',
uploadSuccess: 'Uploaded {count} file(s)',
uploadFailed: 'Upload failed',
saveFailed: 'Save failed',
saved: 'Saved',
unsavedChanges: 'You have unsaved changes. Discard?',
pathCopied: 'Path copied',
fileTooLarge: 'File too large (max 10MB)',
permissionDenied: 'Cannot modify protected file',
notFound: 'File or directory not found',
backendError: 'File operation failed',
dragDropHint: 'Drag files here to upload',
closeEditor: 'Close Editor',
closePreview: 'Close',
saveFile: 'Save',
},
// Download
download: {
downloading: 'Downloading...',
downloadFailed: 'Download failed',
fileNotFound: 'File not found or deleted',
fileTooLarge: 'File too large (exceeds limit)',
backendError: 'File read failed, remote environment may be unavailable',
backendTimeout: 'File read timed out',
unsupportedBackend: 'Current terminal backend does not support file download',
invalidPath: 'Invalid file path',
download: 'Download',
downloadFile: 'Download file',
},
// Changelog
changelog: {
new_0_5_22_1: 'Fix Hermes session list API reading the Web UI local session store instead of the Hermes profile database',
2026-05-15 13:03:03 +08:00
new_0_5_23_1: 'Add bridge-only chat slash commands with localized command suggestions',
new_0_5_23_2: 'Persist command history for session replay without polluting model context, usage, or compression',
new_0_5_23_3: 'Isolate gateway profile environment variables to prevent credentials leaking across profiles',
new_0_5_23_4: 'Reserve the Web UI port during gateway allocation to avoid startup conflicts',
new_0_5_23_5: 'Fix self-update restart handling so successful helper exits are not reported as failures',
2026-05-15 14:47:29 +08:00
new_0_5_24_1: 'Align Bridge chat with API Server handling for multimodal input, system prompt, and workspace context',
2026-05-16 09:40:25 +08:00
new_0_5_25_1: 'Add group chat room reset and clone actions',
new_0_5_25_2: 'Make the Web UI state directory configurable for custom deployment layouts',
new_0_5_25_3: 'Add MiMo as a TTS provider in voice settings',
new_0_5_25_4: 'Fetch custom provider model lists through the backend to avoid browser CORS failures',
new_0_5_25_5: 'Fix tool approval flow for bridge sessions',
new_0_5_25_6: 'Remove the forced CLI platform hint from bridge prompts so custom media/file instructions are preserved',
new_0_5_25_7: 'Show base64 image content correctly in user message history',
new_0_5_25_8: 'Add Playwright browser tests, chat streaming contract coverage, provider model coverage, and coverage baseline',
2026-05-17 10:09:25 +08:00
new_0_5_26_1: 'Support Windows and local Markdown media paths in chat history and rendered messages',
new_0_5_26_2: 'Filter empty assistant history and clear stale compression status when a new run starts',
new_0_5_26_3: 'Add locked file writes for config and profile updates to reduce concurrent write corruption',
new_0_5_26_4: 'Add QQBot and DingTalk channel settings',
new_0_5_26_5: 'Make CLI port detection portable and improve mobile terminal drawer sizing',
new_0_5_26_6: 'Isolate Bridge profile environments and fix Hermes plugin discovery across Python environments',
new_0_5_26_7: 'Explain stopped gateway states with Web UI diagnostics and keep log loading state stable',
new_0_5_26_8: 'Fix session reset mode options, custom provider base URL handling, and dynamic deliver targets',
new_0_5_26_9: 'Add a local tool-call trace visibility toggle in the chat input bar',
new_0_5_26_10: 'Support Hermes Agent package installs when no source checkout is available',
new_0_5_26_11: 'Add xAI Grok OAuth login for SuperGrok subscription users and update Grok model presets',
new_0_5_26_12: 'Expand browser, chat streaming, provider, gateway, config, plugin, and Bridge test coverage',
new_0_5_27_1: 'Add session-level model settings for Bridge chats, with independent provider and model saved per session',
new_0_5_27_2: 'Right-click a Bridge session and choose Set Model to switch the model for that session',
new_0_5_27_3: 'Runs now validate the session model and fall back to the current default model when the saved model is unavailable',
new_0_5_27_4: 'Context compression now follows the current Profile default selected model by default',
2026-05-19 16:19:56 +08:00
new_0_5_30_1: 'Bridge chat now preserves structured history, fixing intermittent no-response and skipped tool execution caused by text-flattened tool history',
new_0_5_30_2: 'Group chat mention routing is more reliable for multiple agents, removes each agents own mention before delivery, and keeps user display names bound after refresh',
new_0_5_30_3: 'Model pages, chat model dropdowns, and session model selection now scope providers and models to the active Profile with accurate default markers',
new_0_5_30_4: 'Gateway management is simplified: the standalone Gateway page is removed, each Profile is checked for platform configuration before starting the needed gateway, and a lightweight gateway runner handles starts and restarts',
new_0_5_30_5: 'Improve Gateway startup across Docker, Termux, and Windows with runtime-lock handling, port-conflict cleanup, background execution, and restart support',
new_0_5_30_6: 'Harden Windows compatibility for path detection, file downloads, and job/update subprocesses so they no longer flash terminal windows',
new_0_5_30_7: 'Fix config writes and provider presets: validate .env keys, route FUN-Codex through the Responses API, and refresh Z.AI/GLM model lists',
new_0_5_30_8: 'Polish frontend details including collapsed sidebar layout, short group labels, sidebar divider, and conversation outline styling',
new_0_5_30_9: 'Context compression now follows Profile compression settings and hardens stale snapshots by reusing previous summaries with a safe tail instead of recompressing full history',
2026-05-20 15:34:09 +08:00
new_0_5_31_1: "Harden Bridge broker restarts, fix final group-chat stream rendering, and add {'@'}all routing for group chat",
new_0_5_31_2: 'File manager can copy absolute paths, and the mobile session drawer overlay no longer falls behind chat content',
new_0_5_31_3: 'Profile selector now shows avatars, custom avatar uploads, runtime status modal, and gateway/profile restart actions',
new_0_5_31_4: 'Profile avatars now appear in single chat, group chat, and collapsed sidebar, with Web UI profile metadata storage and Windows-safe paths',
new_0_5_31_5: 'Improve Docker, Termux, and Windows gateway detection and restart checks by using gateway_state/gateway.pid for managed gateway liveness',
new_0_5_31_6: 'Add APIKEY.FUN image-generation media endpoint and bundled apikey-image-gen skill for text-to-image, image-to-image, and image editing via the active Profile fun-codex provider',
2026-05-21 14:31:52 +08:00
new_0_5_33_1: 'Single chat and group chat now keep run failures and socket errors as red Agent messages in the message list instead of flashing them briefly',
new_0_5_33_2: 'Session search can now scope results to the selected Profile, while still searching all Profiles when no Profile is selected',
new_0_5_33_3: 'Skills page now shows Chinese and English recommendation documents when no skill is selected, and clicking the selected skill again clears the selection',
new_0_5_33_4: 'Remove unused changelog localization entries to reduce frontend i18n size',
new_0_5_33_5: 'Fix agent bridge startup failures on Chinese Windows systems caused by netstat output encoding',
new_0_5_33_6: 'Refresh the Nous Portal preset model list from the public catalog and Portal recommendations',
new_0_5_33_7: 'Profile lists and runtime status now read Profile names from disk and default models from config, avoiding CLI table column-width parsing errors',
2026-05-22 11:12:21 +08:00
new_0_5_34_1: 'Normalize multimodal tool results while storing session and group-chat messages, avoiding base64 image payloads in replays',
new_0_5_34_2: 'Persist custom Hermes models through backend-managed configuration and expose add/remove model endpoints',
new_0_5_34_3: 'Keep Bridge final context usage and tool status updates accurate after runs complete',
new_0_5_34_4: 'Improve Kanban board filtering, assignee display, card actions, and task detail handling',
new_0_5_34_5: 'Fix compression usage accounting by caching fixed prompt/tool context and reporting full-context token totals',
new_0_5_34_6: 'Cache fixed context per group-chat agent and only show compression progress when compression actually starts',
new_0_5_34_7: 'Sync Web UI bundled skills into every Profile and log the target Profile for each injection',
},
}