diff --git a/internal/i18n/catalog_en.go b/internal/i18n/catalog_en.go index ec4b7944..0bb674cf 100644 --- a/internal/i18n/catalog_en.go +++ b/internal/i18n/catalog_en.go @@ -94,12 +94,12 @@ func init() { MsgNotImplemented: "%s not yet implemented", // Agent links - MsgLinksNotConfigured: "agent links not configured", - MsgInvalidDirection: "direction must be outbound, inbound, or bidirectional", - MsgSourceTargetSame: "source and target must be different agents", - MsgCannotDelegateOpen: "cannot delegate to open agents — only predefined agents can be delegation targets", - MsgNoUpdatesProvided: "no updates provided", - MsgInvalidLinkStatus: "status must be active or disabled", + MsgLinksNotConfigured: "agent links not configured", + MsgInvalidDirection: "direction must be outbound, inbound, or bidirectional", + MsgSourceTargetSame: "source and target must be different agents", + MsgCannotDelegateOpen: "cannot delegate to open agents — only predefined agents can be delegation targets", + MsgNoUpdatesProvided: "no updates provided", + MsgInvalidLinkStatus: "status must be active or disabled", // Teams MsgTeamsNotConfigured: "teams not configured", @@ -216,5 +216,8 @@ func init() { MsgHookBudgetExceeded: "tenant hook token budget exceeded", MsgHookPerTurnCapReached: "hook invocation per-turn cap reached", MsgHookBuiltinReadOnly: "builtin hooks are read-only except for the enabled toggle", + + // Message tool cross-target forward notice + MessageCrossTargetForwarded: "📤 Forwarded to %s as requested: %q", }) } diff --git a/internal/i18n/catalog_vi.go b/internal/i18n/catalog_vi.go index 8ddd0527..96546d9f 100644 --- a/internal/i18n/catalog_vi.go +++ b/internal/i18n/catalog_vi.go @@ -94,12 +94,12 @@ func init() { MsgNotImplemented: "%s chưa được triển khai", // Agent links - MsgLinksNotConfigured: "liên kết agent chưa được cấu hình", - MsgInvalidDirection: "hướng phải là outbound, inbound hoặc bidirectional", - MsgSourceTargetSame: "nguồn và đích phải là các agent khác nhau", - MsgCannotDelegateOpen: "không thể ủy quyền cho agent mở — chỉ agent định sẵn mới có thể là đích ủy quyền", - MsgNoUpdatesProvided: "không có cập nhật nào được cung cấp", - MsgInvalidLinkStatus: "trạng thái phải là active hoặc disabled", + MsgLinksNotConfigured: "liên kết agent chưa được cấu hình", + MsgInvalidDirection: "hướng phải là outbound, inbound hoặc bidirectional", + MsgSourceTargetSame: "nguồn và đích phải là các agent khác nhau", + MsgCannotDelegateOpen: "không thể ủy quyền cho agent mở — chỉ agent định sẵn mới có thể là đích ủy quyền", + MsgNoUpdatesProvided: "không có cập nhật nào được cung cấp", + MsgInvalidLinkStatus: "trạng thái phải là active hoặc disabled", // Teams MsgTeamsNotConfigured: "nhóm chưa được cấu hình", @@ -216,5 +216,8 @@ func init() { MsgHookBudgetExceeded: "tenant đã vượt ngân sách token cho hook", MsgHookPerTurnCapReached: "đã đạt giới hạn số lần gọi hook trong một lượt", MsgHookBuiltinReadOnly: "hook dựng sẵn chỉ cho phép bật/tắt, không thể chỉnh sửa", + + // Message tool cross-target forward notice + MessageCrossTargetForwarded: "📤 Đã forward sang %s theo yêu cầu: %q", }) } diff --git a/internal/i18n/catalog_zh.go b/internal/i18n/catalog_zh.go index 7ccf1d00..a42a53bd 100644 --- a/internal/i18n/catalog_zh.go +++ b/internal/i18n/catalog_zh.go @@ -94,12 +94,12 @@ func init() { MsgNotImplemented: "%s 尚未实现", // Agent links - MsgLinksNotConfigured: "Agent链接未配置", - MsgInvalidDirection: "方向必须是 outbound、inbound 或 bidirectional", - MsgSourceTargetSame: "源和目标必须是不同的Agent", - MsgCannotDelegateOpen: "无法委派给开放型Agent — 只有预定义Agent才能作为委派目标", - MsgNoUpdatesProvided: "未提供更新内容", - MsgInvalidLinkStatus: "状态必须是 active 或 disabled", + MsgLinksNotConfigured: "Agent链接未配置", + MsgInvalidDirection: "方向必须是 outbound、inbound 或 bidirectional", + MsgSourceTargetSame: "源和目标必须是不同的Agent", + MsgCannotDelegateOpen: "无法委派给开放型Agent — 只有预定义Agent才能作为委派目标", + MsgNoUpdatesProvided: "未提供更新内容", + MsgInvalidLinkStatus: "状态必须是 active 或 disabled", // Teams MsgTeamsNotConfigured: "团队未配置", @@ -216,5 +216,8 @@ func init() { MsgHookBudgetExceeded: "租户钩子令牌预算已耗尽", MsgHookPerTurnCapReached: "单轮钩子调用次数已达上限", MsgHookBuiltinReadOnly: "内置钩子只读,仅允许切换启用状态", + + // Message tool cross-target forward notice + MessageCrossTargetForwarded: "📤 已按请求转发至 %s:%q", }) } diff --git a/internal/i18n/keys.go b/internal/i18n/keys.go index 2c1e308c..db4f828a 100644 --- a/internal/i18n/keys.go +++ b/internal/i18n/keys.go @@ -4,33 +4,33 @@ package i18n // Grouped by domain for easier maintenance. const ( // --- Common validation --- - MsgRequired = "error.required" // "%s is required" - MsgInvalidID = "error.invalid_id" // "invalid %s ID" - MsgNotFound = "error.not_found" // "%s not found: %s" - MsgAlreadyExists = "error.already_exists" // "%s already exists: %s" - MsgInvalidRequest = "error.invalid_request" // "invalid request: %s" - MsgInvalidJSON = "error.invalid_json" // "invalid JSON" - MsgUnauthorized = "error.unauthorized" // "unauthorized" - MsgPermissionDenied = "error.permission_denied" // "permission denied: %s" - MsgInternalError = "error.internal" // "internal error: %s" - MsgInvalidSlug = "error.invalid_slug" // "%s must be a valid slug (lowercase letters, numbers, hyphens only)" - MsgFailedToList = "error.failed_to_list" // "failed to list %s" - MsgFailedToCreate = "error.failed_to_create" // "failed to create %s: %s" - MsgFailedToUpdate = "error.failed_to_update" // "failed to update %s: %s" - MsgFailedToDelete = "error.failed_to_delete" // "failed to delete %s: %s" - MsgFailedToSave = "error.failed_to_save" // "failed to save %s: %s" - MsgInvalidUpdates = "error.invalid_updates" // "invalid updates" + MsgRequired = "error.required" // "%s is required" + MsgInvalidID = "error.invalid_id" // "invalid %s ID" + MsgNotFound = "error.not_found" // "%s not found: %s" + MsgAlreadyExists = "error.already_exists" // "%s already exists: %s" + MsgInvalidRequest = "error.invalid_request" // "invalid request: %s" + MsgInvalidJSON = "error.invalid_json" // "invalid JSON" + MsgUnauthorized = "error.unauthorized" // "unauthorized" + MsgPermissionDenied = "error.permission_denied" // "permission denied: %s" + MsgInternalError = "error.internal" // "internal error: %s" + MsgInvalidSlug = "error.invalid_slug" // "%s must be a valid slug (lowercase letters, numbers, hyphens only)" + MsgFailedToList = "error.failed_to_list" // "failed to list %s" + MsgFailedToCreate = "error.failed_to_create" // "failed to create %s: %s" + MsgFailedToUpdate = "error.failed_to_update" // "failed to update %s: %s" + MsgFailedToDelete = "error.failed_to_delete" // "failed to delete %s: %s" + MsgFailedToSave = "error.failed_to_save" // "failed to save %s: %s" + MsgInvalidUpdates = "error.invalid_updates" // "invalid updates" // --- Agent --- - MsgAgentNotFound = "error.agent_not_found" // "agent not found: %s" - MsgCannotDeleteDefault = "error.cannot_delete_default" // "cannot delete the default agent" - MsgUserCtxRequired = "error.user_ctx_required" // "user context required" + MsgAgentNotFound = "error.agent_not_found" // "agent not found: %s" + MsgCannotDeleteDefault = "error.cannot_delete_default" // "cannot delete the default agent" + MsgUserCtxRequired = "error.user_ctx_required" // "user context required" // --- Chat --- - MsgRateLimitExceeded = "error.rate_limit" // "rate limit exceeded — please wait" - MsgNoUserMessage = "error.no_user_message" // "no user message found" - MsgUserIDRequired = "error.user_id_required" // "user_id is required" - MsgMsgRequired = "error.message_required" // "message is required" + MsgRateLimitExceeded = "error.rate_limit" // "rate limit exceeded — please wait" + MsgNoUserMessage = "error.no_user_message" // "no user message found" + MsgUserIDRequired = "error.user_id_required" // "user_id is required" + MsgMsgRequired = "error.message_required" // "message is required" // --- Abort --- MsgAbortStopped = "abort.stopped" // "run stopped" @@ -60,30 +60,30 @@ const ( MsgSenderIDRequired = "error.sender_id_required" // "sender_id is required" // --- HTTP API --- - MsgInvalidAuth = "error.invalid_auth" // "invalid authentication" - MsgMsgsRequired = "error.messages_required" // "messages is required" - MsgUserIDHeader = "error.user_id_header" // "X-GoClaw-User-Id header is required" - MsgFileTooLarge = "error.file_too_large" // "file too large or invalid multipart form" - MsgMissingFileField = "error.missing_file_field" // "missing 'file' field" - MsgInvalidFilename = "error.invalid_filename" // "invalid filename" - MsgChannelKeyReq = "error.channel_key_required" // "channel and key are required" - MsgMethodNotAllowed = "error.method_not_allowed" // "method not allowed" - MsgStreamingNotSupported = "error.streaming_not_supported" // "streaming not supported" - MsgOwnerOnly = "error.owner_only" // "only owner can %s" - MsgNoAccess = "error.no_access" // "no access to this %s" - MsgAlreadySummoning = "error.already_summoning" // "agent is already being summoned" - MsgSummoningUnavailable = "error.summoning_unavailable" // "summoning not available" - MsgNoDescription = "error.no_description" // "agent has no description to resummon from" - MsgSummonCancelled = "info.summon_cancelled" // "summon cancelled by user" - MsgCannotCancel = "error.cannot_cancel_summon" // "agent is not being summoned" - MsgInvalidPath = "error.invalid_path" // "invalid path" + MsgInvalidAuth = "error.invalid_auth" // "invalid authentication" + MsgMsgsRequired = "error.messages_required" // "messages is required" + MsgUserIDHeader = "error.user_id_header" // "X-GoClaw-User-Id header is required" + MsgFileTooLarge = "error.file_too_large" // "file too large or invalid multipart form" + MsgMissingFileField = "error.missing_file_field" // "missing 'file' field" + MsgInvalidFilename = "error.invalid_filename" // "invalid filename" + MsgChannelKeyReq = "error.channel_key_required" // "channel and key are required" + MsgMethodNotAllowed = "error.method_not_allowed" // "method not allowed" + MsgStreamingNotSupported = "error.streaming_not_supported" // "streaming not supported" + MsgOwnerOnly = "error.owner_only" // "only owner can %s" + MsgNoAccess = "error.no_access" // "no access to this %s" + MsgAlreadySummoning = "error.already_summoning" // "agent is already being summoned" + MsgSummoningUnavailable = "error.summoning_unavailable" // "summoning not available" + MsgNoDescription = "error.no_description" // "agent has no description to resummon from" + MsgSummonCancelled = "info.summon_cancelled" // "summon cancelled by user" + MsgCannotCancel = "error.cannot_cancel_summon" // "agent is not being summoned" + MsgInvalidPath = "error.invalid_path" // "invalid path" // --- Tenant backup / restore --- MsgRestoreNewModeRejectsTenantID = "error.restore_new_mode_rejects_tenant_id" // "mode=new uses tenant_slug; tenant_id is not accepted" // --- Scheduler --- - MsgQueueFull = "error.queue_full" // "session queue is full" - MsgShuttingDown = "error.shutting_down" // "gateway is shutting down, please retry shortly" + MsgQueueFull = "error.queue_full" // "session queue is full" + MsgShuttingDown = "error.shutting_down" // "gateway is shutting down, please retry shortly" // --- Provider --- MsgProviderReqFailed = "error.provider_request_failed" // "%s: request failed: %s" @@ -95,12 +95,12 @@ const ( MsgNotImplemented = "error.not_implemented" // "%s not yet implemented" // --- Agent links --- - MsgLinksNotConfigured = "error.links_not_configured" // "agent links not configured" - MsgInvalidDirection = "error.invalid_direction" // "direction must be outbound, inbound, or bidirectional" - MsgSourceTargetSame = "error.source_target_same" // "source and target must be different agents" - MsgCannotDelegateOpen = "error.cannot_delegate_open" // "cannot delegate to open agents — only predefined agents can be delegation targets" - MsgNoUpdatesProvided = "error.no_updates_provided" // "no updates provided" - MsgInvalidLinkStatus = "error.invalid_link_status" // "status must be active or disabled" + MsgLinksNotConfigured = "error.links_not_configured" // "agent links not configured" + MsgInvalidDirection = "error.invalid_direction" // "direction must be outbound, inbound, or bidirectional" + MsgSourceTargetSame = "error.source_target_same" // "source and target must be different agents" + MsgCannotDelegateOpen = "error.cannot_delegate_open" // "cannot delegate to open agents — only predefined agents can be delegation targets" + MsgNoUpdatesProvided = "error.no_updates_provided" // "no updates provided" + MsgInvalidLinkStatus = "error.invalid_link_status" // "status must be active or disabled" // --- Teams --- MsgTeamsNotConfigured = "error.teams_not_configured" // "teams not configured" @@ -108,8 +108,8 @@ const ( MsgCannotRemoveTeamLead = "error.cannot_remove_team_lead" // "cannot remove the team lead" // --- Channels --- - MsgCannotDeleteDefaultInst = "error.cannot_delete_default_inst" // "cannot delete default channel instance" - MsgCannotRemoveLastWriter = "error.cannot_remove_last_writer" // "cannot remove the last file writer" + MsgCannotDeleteDefaultInst = "error.cannot_delete_default_inst" // "cannot delete default channel instance" + MsgCannotRemoveLastWriter = "error.cannot_remove_last_writer" // "cannot remove the last file writer" // --- Skills --- MsgSkillsUpdateNotSupported = "error.skills_update_not_supported" // "skills.update not supported for file-based skills" @@ -119,10 +119,10 @@ const ( MsgInvalidLogAction = "error.invalid_log_action" // "action must be 'start' or 'stop'" // --- Config --- - MsgRawConfigRequired = "error.raw_config_required" // "raw config is required" - MsgRawPatchRequired = "error.raw_patch_required" // "raw patch is required" - MsgConfigMasterScopeOnly = "error.config_master_scope_only" // "config.* methods are master-scope only" - MsgMasterScopeRequired = "error.master_scope_required" // "this action requires master tenant scope" + MsgRawConfigRequired = "error.raw_config_required" // "raw config is required" + MsgRawPatchRequired = "error.raw_patch_required" // "raw patch is required" + MsgConfigMasterScopeOnly = "error.config_master_scope_only" // "config.* methods are master-scope only" + MsgMasterScopeRequired = "error.master_scope_required" // "this action requires master tenant scope" // --- Storage / File --- MsgCannotDeleteSkillsDir = "error.cannot_delete_skills_dir" // "cannot delete skills directories" @@ -133,7 +133,7 @@ const ( MsgFailedToDeleteFile = "error.failed_to_delete_file" // "failed to delete" // --- OAuth --- - MsgNoPendingOAuth = "error.no_pending_oauth" // "no pending OAuth flow" + MsgNoPendingOAuth = "error.no_pending_oauth" // "no pending OAuth flow" MsgFailedToSaveToken = "error.failed_to_save_token" // "failed to save token" // --- Intent Classify (channel-facing status replies) --- @@ -148,44 +148,45 @@ const ( MsgInjectedAck = "status.injected_ack" // "Got it, I'll incorporate that into what I'm working on." // --- Knowledge Graph --- - MsgEntityIDRequired = "error.entity_id_required" // "entity_id is required" - MsgEntityFieldsRequired = "error.entity_fields_required" // "external_id, name, and entity_type are required" - MsgTextRequired = "error.text_required" // "text is required" - MsgProviderModelRequired = "error.provider_model_required" // "provider and model are required" - MsgInvalidProviderOrModel = "error.invalid_provider_or_model" // "invalid provider or model" + MsgEntityIDRequired = "error.entity_id_required" // "entity_id is required" + MsgEntityFieldsRequired = "error.entity_fields_required" // "external_id, name, and entity_type are required" + MsgTextRequired = "error.text_required" // "text is required" + MsgProviderModelRequired = "error.provider_model_required" // "provider and model are required" + MsgInvalidProviderOrModel = "error.invalid_provider_or_model" // "invalid provider or model" // --- Builtin tool descriptions (i18n key = core.tool.) --- - MsgToolReadFile = "core.tool.read_file" - MsgToolWriteFile = "core.tool.write_file" - MsgToolListFiles = "core.tool.list_files" - MsgToolEdit = "core.tool.edit" - MsgToolExec = "core.tool.exec" - MsgToolWebSearch = "core.tool.web_search" - MsgToolWebFetch = "core.tool.web_fetch" - MsgToolMemorySearch = "core.tool.memory_search" - MsgToolMemoryGet = "core.tool.memory_get" - MsgToolKGSearch = "core.tool.knowledge_graph_search" - MsgToolReadImage = "core.tool.read_image" - MsgToolReadDocument = "core.tool.read_document" - MsgToolCreateImage = "core.tool.create_image" - MsgToolReadAudio = "core.tool.read_audio" - MsgToolReadVideo = "core.tool.read_video" - MsgToolCreateVideo = "core.tool.create_video" - MsgToolCreateAudio = "core.tool.create_audio" - MsgToolTTS = "core.tool.tts" - MsgToolBrowser = "core.tool.browser" - MsgToolSessionsList = "core.tool.sessions_list" - MsgToolSessionStatus = "core.tool.session_status" - MsgToolSessionsHistory = "core.tool.sessions_history" - MsgToolSessionsSend = "core.tool.sessions_send" - MsgToolMessage = "core.tool.message" - MsgToolCron = "core.tool.cron" - MsgToolSpawn = "core.tool.spawn" - MsgToolSkillSearch = "core.tool.skill_search" - MsgToolUseSkill = "core.tool.use_skill" - MsgToolSkillManage = "core.tool.skill_manage" - MsgToolPublishSkill = "core.tool.publish_skill" - MsgToolTeamTasks = "core.tool.team_tasks" + MsgToolReadFile = "core.tool.read_file" + MsgToolWriteFile = "core.tool.write_file" + MsgToolListFiles = "core.tool.list_files" + MsgToolEdit = "core.tool.edit" + MsgToolExec = "core.tool.exec" + MsgToolWebSearch = "core.tool.web_search" + MsgToolWebFetch = "core.tool.web_fetch" + MsgToolMemorySearch = "core.tool.memory_search" + MsgToolMemoryGet = "core.tool.memory_get" + MsgToolKGSearch = "core.tool.knowledge_graph_search" + MsgToolReadImage = "core.tool.read_image" + MsgToolReadDocument = "core.tool.read_document" + MsgToolCreateImage = "core.tool.create_image" + MsgToolReadAudio = "core.tool.read_audio" + MsgToolReadVideo = "core.tool.read_video" + MsgToolCreateVideo = "core.tool.create_video" + MsgToolCreateAudio = "core.tool.create_audio" + MsgToolTTS = "core.tool.tts" + MsgToolBrowser = "core.tool.browser" + MsgToolSessionsList = "core.tool.sessions_list" + MsgToolSessionStatus = "core.tool.session_status" + MsgToolSessionsHistory = "core.tool.sessions_history" + MsgToolSessionsSend = "core.tool.sessions_send" + MsgToolMessage = "core.tool.message" + MessageCrossTargetForwarded = "tools.message.cross_target_forwarded" + MsgToolCron = "core.tool.cron" + MsgToolSpawn = "core.tool.spawn" + MsgToolSkillSearch = "core.tool.skill_search" + MsgToolUseSkill = "core.tool.use_skill" + MsgToolSkillManage = "core.tool.skill_manage" + MsgToolPublishSkill = "core.tool.publish_skill" + MsgToolTeamTasks = "core.tool.team_tasks" // Skill evolution nudges (user-facing) MsgSkillNudgePostscript = "skill.nudge_postscript" @@ -196,28 +197,28 @@ const ( MsgInvalidRole = "error.invalid_role" // "invalid role: allowed values are owner, admin, operator, member, viewer" // --- TTS / Voices --- - MsgTtsUnknownModel = "error.tts_unknown_model" // "unknown tts model: %s" - MsgVoicesListFailed = "error.voices_list_failed" // "failed to list voices: %s" + MsgTtsUnknownModel = "error.tts_unknown_model" // "unknown tts model: %s" + MsgVoicesListFailed = "error.voices_list_failed" // "failed to list voices: %s" // --- STT --- - MsgSTTAllProvidersFailed = "error.stt_all_providers_failed" // "All STT providers failed" + MsgSTTAllProvidersFailed = "error.stt_all_providers_failed" // "All STT providers failed" MsgSTTLegacyConfigDeprecated = "warn.stt_legacy_config_deprecated" // "Legacy STT config deprecated; migrate to builtin_tools[stt]" MsgSTTWhatsappPrivacyWarning = "warn.stt_whatsapp_privacy" // "Enabling STT for WhatsApp breaks end-to-end encryption for voice messages sent to this agent." - MsgVoiceMessageFallback = "channel.voice_message_fallback" // "[Voice message]" — used when STT unavailable/disabled/timed-out + MsgVoiceMessageFallback = "channel.voice_message_fallback" // "[Voice message]" — used when STT unavailable/disabled/timed-out // --- Contact merge --- MsgContactIDsRequired = "error.contact_ids_required" // "contact_ids is required" - MsgMergeTargetRequired = "error.merge_target_required" // "exactly one of tenant_user_id or create_user is required" - MsgTenantUserNotFound = "error.tenant_user_not_found" // "tenant user not found" - MsgTenantMismatch = "error.tenant_mismatch" // "tenant user does not belong to this tenant" - MsgTenantScopeRequired = "error.tenant_scope_required" // "tenant scope is required for this operation" + MsgMergeTargetRequired = "error.merge_target_required" // "exactly one of tenant_user_id or create_user is required" + MsgTenantUserNotFound = "error.tenant_user_not_found" // "tenant user not found" + MsgTenantMismatch = "error.tenant_mismatch" // "tenant user does not belong to this tenant" + MsgTenantScopeRequired = "error.tenant_scope_required" // "tenant scope is required for this operation" // --- Hooks --- - MsgHookInvalidMatcher = "hook.invalid_matcher" // "invalid matcher regex: %s" - MsgHookCommandDisabledStandard = "hook.command_disabled_standard" // "command-type hooks are only available on Lite edition" - MsgHookPromptRequiresMatcher = "hook.prompt_requires_matcher" // "prompt hooks require a matcher or if_expr (runaway-cost guard)" - MsgHookCircuitBreakerTripped = "hook.circuit_breaker_tripped" // "hook auto-disabled after repeated failures" - MsgHookBudgetExceeded = "hook.budget_exceeded" // "tenant hook token budget exceeded" - MsgHookPerTurnCapReached = "hook.per_turn_cap_reached" // "hook invocation per-turn cap reached" - MsgHookBuiltinReadOnly = "hook.builtin_readonly" // "builtin hooks are read-only except for the enabled toggle" + MsgHookInvalidMatcher = "hook.invalid_matcher" // "invalid matcher regex: %s" + MsgHookCommandDisabledStandard = "hook.command_disabled_standard" // "command-type hooks are only available on Lite edition" + MsgHookPromptRequiresMatcher = "hook.prompt_requires_matcher" // "prompt hooks require a matcher or if_expr (runaway-cost guard)" + MsgHookCircuitBreakerTripped = "hook.circuit_breaker_tripped" // "hook auto-disabled after repeated failures" + MsgHookBudgetExceeded = "hook.budget_exceeded" // "tenant hook token budget exceeded" + MsgHookPerTurnCapReached = "hook.per_turn_cap_reached" // "hook invocation per-turn cap reached" + MsgHookBuiltinReadOnly = "hook.builtin_readonly" // "builtin hooks are read-only except for the enabled toggle" )