From ffbd3e9a2b81551e079557c3658e490d0fe9fb8e Mon Sep 17 00:00:00 2001 From: SaladDay <1203511142@qq.com> Date: Wed, 14 Oct 2026 07:56:38 +0000 Subject: [PATCH 1/8] Delete unused console copy and legacy hash aliases --- apps/web/src/i18n/README.md | 2 +- apps/web/src/i18n/locales/en/agents.ts | 45 ++-------- apps/web/src/i18n/locales/en/common.ts | 1 - apps/web/src/i18n/locales/en/dashboard.ts | 20 ----- apps/web/src/i18n/locales/en/files.ts | 17 ---- apps/web/src/i18n/locales/en/navigation.ts | 8 -- apps/web/src/i18n/locales/en/overview.ts | 11 --- apps/web/src/i18n/locales/en/pages.ts | 8 +- apps/web/src/i18n/locales/en/sessions.ts | 31 +------ apps/web/src/i18n/locales/en/skills.ts | 83 ------------------- apps/web/src/i18n/locales/en/system.ts | 1 - apps/web/src/i18n/locales/en/templates.ts | 12 +-- apps/web/src/i18n/locales/en/vaults.ts | 35 ++------ apps/web/src/i18n/locales/zh-CN/agents.ts | 27 +----- apps/web/src/i18n/locales/zh-CN/common.ts | 1 - apps/web/src/i18n/locales/zh-CN/dashboard.ts | 20 ----- apps/web/src/i18n/locales/zh-CN/files.ts | 17 ---- apps/web/src/i18n/locales/zh-CN/navigation.ts | 8 -- apps/web/src/i18n/locales/zh-CN/overview.ts | 11 --- apps/web/src/i18n/locales/zh-CN/pages.ts | 8 +- apps/web/src/i18n/locales/zh-CN/sandbox.ts | 59 ------------- apps/web/src/i18n/locales/zh-CN/sessions.ts | 32 +------ apps/web/src/i18n/locales/zh-CN/skills.ts | 83 ------------------- apps/web/src/i18n/locales/zh-CN/system.ts | 1 - apps/web/src/i18n/locales/zh-CN/templates.ts | 13 +-- apps/web/src/i18n/locales/zh-CN/vaults.ts | 10 +-- apps/web/src/i18n/resources.ts | 4 - apps/web/src/lib/console-routes.test.ts | 7 +- apps/web/src/lib/console-routes.ts | 12 +-- 29 files changed, 36 insertions(+), 551 deletions(-) delete mode 100644 apps/web/src/i18n/locales/en/dashboard.ts delete mode 100644 apps/web/src/i18n/locales/zh-CN/dashboard.ts diff --git a/apps/web/src/i18n/README.md b/apps/web/src/i18n/README.md index 51cda8d31..90e6c40c3 100644 --- a/apps/web/src/i18n/README.md +++ b/apps/web/src/i18n/README.md @@ -4,7 +4,7 @@ The console uses `i18next` and `react-i18next`. English is the fallback language Translations are split by namespace, registered in `resources.ts`: -- `locales/en/*.ts` and `locales/zh-CN/*.ts` hold one file per feature namespace: `common` (reusable actions and labels, with the Core error messages of `core-errors.ts` nested inside it), `navigation` (the shell), `pages`, `agents`, `templates`, `vaults`, `files`, `skills`, `keys`, `sessions`, `diagnostics`, `dashboard`, `overview`, `metrics`, `system`, `sandbox-navigation` (registered as `sandboxNavigation`) and `onboarding`. +- `locales/en/*.ts` and `locales/zh-CN/*.ts` hold one file per feature namespace: `common` (reusable actions and labels, with the Core error messages of `core-errors.ts` nested inside it), `navigation` (the shell), `pages`, `agents`, `templates`, `vaults`, `files`, `skills`, `keys`, `sessions`, `diagnostics`, `overview`, `metrics`, `system`, `onboarding`, `sandbox-navigation` (registered as `sandboxNavigation`), `request-log` (`requestLog`) and `workspace-storage` (`workspaceStorage`). - `sandbox` and `firstRun` use English text as keys in `locales/zh-CN/sandbox.ts` and `locales/zh-CN/first-run.ts`; `resources.ts` projects those keys into the English resources. Keep these keys unchanged when moving copy. Add a namespace when a feature grows beyond page-level labels; do not grow one application-wide translation object. diff --git a/apps/web/src/i18n/locales/en/agents.ts b/apps/web/src/i18n/locales/en/agents.ts index 8ad49e59d..5f0add8cc 100644 --- a/apps/web/src/i18n/locales/en/agents.ts +++ b/apps/web/src/i18n/locales/en/agents.ts @@ -1,21 +1,11 @@ export const agents = { - loading: "Loading Agents", requestFailed: "The OpenAgentCore request failed.", - searchPlaceholder: "Search name, model, or ID…", filtersLabel: "Agent filters", searchLabel: "Search Agents", refreshLabel: "Refresh Agents", - loadFailed: "Couldn’t load Agents", refreshFailed: "Couldn’t refresh Agents", staleDescription: "The last loaded Agent configurations remain available.", - loadDescription: "The Web could not read Agent configurations from the connected OpenAgentCore.", connectionHint: "Check the OpenAgentCore connection in the sidebar, then retry.", - openFailed: "Couldn’t open the latest Agent", retry: "Retry", requestFailure: "Request failed", - errors: { - retrievalUnavailable: "Agent retrieval is unavailable for this OpenAgentCore connection.", interrupted: "The Agent request was interrupted by a connection change.", differentRetrieved: "OpenAgentCore returned a different Agent than the one requested.", - updateUnavailable: "Agent updates are unavailable for this OpenAgentCore connection.", updateInterrupted: "The Agent update was interrupted by a connection change.", differentUpdated: "OpenAgentCore returned a different Agent than the one updated.", deleteUnavailable: "Delete is unavailable for this OpenAgentCore connection.", - modelRequired: "Enter a model ID.", nameTooLong: "Name must be at most 128 characters.", metadataJson: "Metadata must be valid JSON.", metadataObject: "Metadata must be a JSON object.", metadataStrings: "Every metadata value must be a string.", metadataCount: "Agent metadata supports at most 16 pairs.", metadataLength: "Metadata keys must be at most 64 characters and values at most 512 characters.", - reasoningDefault: "Current Core Sessions require both reasoning fields to use Core default.", serviceTier: "Current Core Sessions support service tier auto only.", textFormat: "Current Core Sessions support text format only.", verbosity: "Low and high verbosity require a discovered compatible Codex model; use medium for this Web flow.", - readOnlyTools: "Tools cannot be changed while this Agent contains read-only saved tool definitions.", functionName: "Every Function needs a non-empty name.", functionNameLength: "Function names must be at most 512 UTF-8 bytes.", functionUnique: "Function names must be unique.", functionJson: "Function {{name}} parameters must be valid JSON.", functionSchema: "Function {{name}} parameters must be a JSON object schema.", - mcpLabel: "Every MCP server needs a non-empty label.", mcpUnique: "MCP server labels must be unique.", mcpUrl: "MCP server {{name}} needs a valid anonymous HTTP(S) URL.", credentialMissing: "MCP server {{name}} references a Credential that is not available in the current catalog.", credentialUrl: "MCP server {{name}} must use the selected Credential's exact URL.", functionCount: "At most 64 Functions can be configured.", - }, + loading: "Loading Agents", + searchPlaceholder: "Search name, model, or ID…", refreshLabel: "Refresh Agents", + loadFailed: "Couldn’t load Agents", refreshFailed: "Couldn’t refresh Agents", retry: "Retry", view: { filterLabel: "Filter Agents", searchPlaceholder: "Search name, model or ID", - columns: { agent: "Agent", model: "Model", harness: "Harness", tools: "Tools", sessions: "Sessions", tokens: "Tokens", lastActive: "Last active", updated: "Updated", actions: "Actions" }, + columns: { agent: "Agent", model: "Model", harness: "Harness", tools: "Tools", sessions: "Sessions", tokens: "Tokens", lastActive: "Last active", actions: "Actions" }, open: "Open {{name}}", coreDefault: "Core default", back: "Back", @@ -63,31 +53,10 @@ export const agents = { delete: "Delete", }, catalog: { - listLabel: "Agents", create: "Create agent", untitled: "Untitled Agent", editLabel: "Edit {{name}} ({{id}})", opening: "Opening latest definition…", - startLabel: "Start a Session with {{name}} ({{id}})", unavailable: "Unavailable", startSession: "Start Session", sessionUnavailable: "Session unavailable: {{reason}}", - noMatch: "No matching Agents", noSaved: "No Agents yet", clearSearch: "Clear search", - columns: { agent: "Agent", model: "Model", harness: "Harness", tools: "Tools", updated: "Updated", actions: "Actions" }, coreDefaultHarness: "Core default", copyId: "Copy Agent ID {{id}}", copied: "Copied", unavailableHelp: "Why a Session cannot start", + listLabel: "Agents", untitled: "Untitled Agent", + noMatch: "No matching Agents", noSaved: "No Agents yet", }, details: { - id: "ID", created: "Created", updated: "Updated", model: "Model", name: "Name", instructions: "Instructions", metadata: "Metadata", notSet: "Not set", none: "None", - blocked: "This Agent can be saved, but the known Core Session profile cannot start it: {{reason}}", runtimeBoundary: "Saved advanced configuration is not runtime proof. Model, provider, host, tools, and conditional verbosity still require executor validation.", advanced: "Advanced configuration · read only", tools: "Tools", reasoning: "Reasoning", text: "Text", serviceTier: "Service tier", multiAgent: "Multi-agent", functionTool: "Function {{name}}", mcpTool: "{{auth}} service-origin HTTP MCP {{name}}", serviceOriginMcp: "service-origin HTTP MCP", vaultBearer: "Vault bearer", anonymous: "Anonymous", readOnly: "{{label}} · read only", - deletePrompt: "Delete {{name}} from OpenAgentCore?", deleteBefore: "Delete", deleteAfter: "from OpenAgentCore?", exactId: "Exact Agent ID: {{id}}", exactIdLabel: "Exact Agent ID:", deleteWarning: "This removes the saved Agent only after Core confirms success. Existing Sessions keep their durable Agent snapshots.", deleteTitle: "Delete Agent?", cancel: "Cancel", deleting: "Deleting…", - }, - savedTool: { malformed: "Malformed saved tool definition", toolSearch: "tool_search is saved-only and cannot run in a Session", programmatic: "programmatic_tool_calling is saved-only and cannot run in a Session", webSearchDisabled: "Disabled web_search is read-only in Web; Sessions keep search off", webSearchEnabled: "Enabled web_search is saved-only; Core does not run enabled search in a Session", deferred: "Deferred Function is saved-only", credentialedMcp: "Credentialed MCP is unresolved or URL-mismatched in the current Vault catalog", unsupportedFunction: "Unsupported Function tool definition", unsupportedMcp: "Unsupported MCP tool definition", unsupported: "Unsupported saved tool definition" }, - admission: { - model: "a non-empty model is required", multiAgent: "multi-agent execution is not supported", reasoning: "explicit reasoning options are saved-only", serviceTier: "service tier must be auto", text: "text format must be text", malformedTool: "the saved tool configuration is not executable", malformedFunction: "the saved function tool is incomplete or malformed", deferred: "deferred functions are saved-only", functionName: "function names must be non-empty and at most 512 bytes", functionUnique: "function names must be unique", malformedMcp: "the saved MCP tool is incomplete or malformed", credential: "attached MCP credentials are unavailable in this Web Session flow", mcpUnique: "MCP server labels must be unique", malformedWebSearch: "the saved web_search tool is incomplete or malformed", enabledWebSearch: "web_search mode must be disabled because Core does not run enabled search", savedOnly: "{{type}} is saved-only", unsupportedTool: "the saved tool type is not executable", functionCount: "at most 64 function tools can execute", webSearchCount: "at most one web_search tool can execute", coreRequires: "Current Core Session admission requires {{reasons}}.", vaultUnavailable: "Session Vault attachment is unavailable. {{reason}}", managedMcp: "Managed hosted Sessions do not yet support MCP tools. Choose no Environment or self-hosted, or use a Function-only Agent.", - }, - usage: { - title: "Usage", rangeLabel: "Sessions created", ranges: { all: "All time", "7d": "Last 7 days", "30d": "Last 30 days" }, - help: "Usage is each Session's cumulative total as reported by Core; it is not split by day. A Session belongs to the range in which it was created, and all of its usage counts there.", - caveat: "Data comes from cumulative Session usage reported by Core. It excludes unreported usage and is not a basis for billing.", - reading: "Reading Sessions… {{formattedCount}} read", cancel: "Cancel", cancelled_one: "Stopped after reading {{formattedCount}} Session.", cancelled_other: "Stopped after reading {{formattedCount}} Sessions.", continue: "Continue", failed: "Couldn’t read Sessions.", retry: "Retry", - large: "More than {{formattedCount}} Sessions: statistics may be slow. Try a shorter time range first.", largeShortest: "More than {{formattedCount}} Sessions: statistics may be slow.", - sessions: "Sessions", tokens: "Tokens", coverage: "Coverage", lastActive: "Last active", noData: "No data", cardLabel: "Usage of {{name}}", - coverageHelp: "Sessions whose usage Core reported, out of all Sessions in the range. Sessions without reported usage are left out of token totals, not counted as zero.", - coverageDetail_one: "{{reported}} of {{formattedCount}} Session reported usage", coverageDetail_other: "{{reported}} of {{formattedCount}} Sessions reported usage", - status: "Status", statuses: { in_progress: "In progress", requires_action: "Requires action", failed: "Failed", idle: "Idle", unknown: "Unrecognized" }, - tokenKinds: { input: "Input", output: "Output", total: "Total", cached: "Cached input", reasoning: "Reasoning" }, - other: { title: "Other Agents", help: "Sessions whose Agent ID is not in the current Agent list: the Agent was deleted, or the Session was created with an inline Agent configuration. Grouped by the raw Agent ID.", agentId: "Agent ID", missingId: "No Agent ID", showAll: "Show all {{formattedCount}}", showLess: "Show less" }, + reasoning: "Reasoning", }, } as const; diff --git a/apps/web/src/i18n/locales/en/common.ts b/apps/web/src/i18n/locales/en/common.ts index 12698b620..a19131fb1 100644 --- a/apps/web/src/i18n/locales/en/common.ts +++ b/apps/web/src/i18n/locales/en/common.ts @@ -71,6 +71,5 @@ export const common = { loadedMore: "{{n}} loaded · more available", noMatches: "No matches", deleteUncertain: "The deletion was not confirmed; Core may or may not have removed it. The view was re-read, so check it before trying again.", - noMatchesDescription: "Nothing matches the current search or filters.", }, } as const; diff --git a/apps/web/src/i18n/locales/en/dashboard.ts b/apps/web/src/i18n/locales/en/dashboard.ts deleted file mode 100644 index 7bc2f2904..000000000 --- a/apps/web/src/i18n/locales/en/dashboard.ts +++ /dev/null @@ -1,20 +0,0 @@ -export const dashboard = { - trends: { - title: "Resource trends", retained: "Retained samples · durable history", local: "Browser-local samples · reset on reload", source: "Runtime metric source", live: "Live", history: "History", - historyStale: "History stale", historyLoading: "History · loading", durableResolution: "Durable · {{seconds}}s", liveRetrying: "Live · history retrying", liveUnavailable: "Live · history unavailable", liveLoading: "Live · loading history", staleRetrying: "Stale · retrying", liveInterval: "Live · {{seconds}}s", - durableStatus: "{{status}}; {{count}} Runtime targets", retainedFailure: "Runtime sampling refresh failed; showing retained samples", samplingInterval: "Live Runtime sampling every {{seconds}} seconds", - bucket: "bucket", buckets: "buckets", sample: "sample", samples: "samples", observations: "{{actual}}/{{expected}} observations", durableRange: "Runtime durable range", liveRange: "Runtime live range", - refreshFailed: "Durable history refresh failed: {{error}}", notConfigured: "Durable history is not configured; Live samples remain available.", requestFailed: "Durable Runtime history request failed.", - }, - charts: { - collecting: "Collecting live samples", durableHistory: "durable history", live: "live", retainedBuckets: "retained buckets", liveSamples: "live samples", chartLabel: "{{title}} {{source}} chart", - hideSeries: "Hide {{series}} series", showSeries: "Show {{series}} series", hide: "Hide {{series}}", show: "Show {{series}}", resetZoom: "Reset zoom", - instructions: "Move the pointer over the plot for exact values. Drag horizontally to select and zoom a time range. Double-click or use Reset zoom to restore the full range. Click to pin a time. Use Left and Right arrows to move the pinned selection, and Escape to clear it.", - pinned: "Pinned", hover: "Hover", unavailable: "Unavailable", allHidden: "All series hidden", sparse: "Sparse samples", showLegend: "Use the legend to show a series", sparseDetail: "{{count}} valid points · a line requires consecutive buckets", emptyDetail: "{{valid}}/2 valid points · {{count}} snapshots · no history is synthesized", - table: { series: "Series", latest: "Latest value", missing: "Missing samples" }, runtime: "Runtime", usage: "usage", used: "used", configuredLimit: "configured limit", input: "input", output: "output", gridDurable: "Runtime durable-history charts", gridLive: "Runtime live-window charts", - cpu: { title: "CPU usage", withoutData: "{{count}} runtime targets have no CPU data in this range", durable: "bucketed cumulative-delta utilization · durable history", live: "reported or cumulative-delta utilization · live window", empty: "No retained CPU samples" }, - memory: { title: "Memory usage", durable: "observed Sandbox aggregate / configured limit · durable history", live: "observed Sandbox working set / configured limit · live window", empty: "No retained observed memory samples" }, - active: { series: "active", sandboxTitle: "Active sandboxes", runtimeTitle: "Runtime active", sumDurable: "observed allocations per retained bucket · durable history", sumLive: "lifecycle state active allocations per snapshot · live window", binaryDurable: "observed allocation in retained bucket · 1 active / 0 inactive", binaryLive: "lifecycle state active · 1 active / 0 inactive", active: "Active", inactive: "Inactive", empty: "No retained active Sandbox samples" }, - tokens: { title: "Token throughput", durable: "canonical Session Usage deltas · durable history", live: "Session Usage deltas · missing usage excluded", empty: "No retained token samples", perMinute: "{{value}}/min" }, - }, -} as const; diff --git a/apps/web/src/i18n/locales/en/files.ts b/apps/web/src/i18n/locales/en/files.ts index 0834384cb..1d74b0607 100644 --- a/apps/web/src/i18n/locales/en/files.ts +++ b/apps/web/src/i18n/locales/en/files.ts @@ -31,37 +31,20 @@ export const files = { size: "Size", created: "Created", purpose: "Purpose", - id: "File ID", actions: "Actions", exactBytes: "{{bytes}} bytes", unrecognized: "Unrecognized file", unrecognizedHelp: "Core returned metadata this console does not recognize, so only the File ID is shown.", noMatchTitle: "No loaded files match", - noMatchDescription: "The filter covers loaded files only. Load more files or clear the filter.", - loadFailed: "Files could not be loaded", - refreshFailed: "The list could not be refreshed: {{reason}}", moreFailed: "More files could not be loaded: {{reason}}", }, empty: { title: "No files yet", }, - unsupported: { - title: "This Core does not list files", - description: "The Files list returned HTTP {{status}}.", - }, - upload: { - uploading: "Uploading {{name}}…", - uploaded: "Uploaded {{name}}", - tooLarge: "{{name}} is larger than 512 MiB, the upload limit.", - badName: "A file name must be 1 to 1024 UTF-8 bytes and cannot contain NUL characters.", - rejected: "Core rejected the upload of {{name}}: {{reason}}", - uncertain: "The upload of {{name}} may have reached Core. Refresh the list to check before uploading it again.", - }, delete: { prompt: "Delete {{name}}?", consequences: "Copies already placed in Session workspaces are not affected, and neither are existing Sessions. New Sessions from an Environment Template that references this File ID will fail.", deleted: "Deleted {{name}}", - missing: "{{name}} was already deleted.", rejected: "Core rejected the deletion: {{reason}}", uncertain: "The deletion of {{name}} was not confirmed. Refresh the list to check before trying again.", }, diff --git a/apps/web/src/i18n/locales/en/navigation.ts b/apps/web/src/i18n/locales/en/navigation.ts index d285561a6..244124535 100644 --- a/apps/web/src/i18n/locales/en/navigation.ts +++ b/apps/web/src/i18n/locales/en/navigation.ts @@ -27,19 +27,11 @@ export const navigation = { settings: {"sandbox": "Sandbox and scheduling", "storage": "Workspace storage", "models": "Models and credentials", "service": "Service and deployment"}, showGettingStarted: "Show Getting started", skipToContent: "Skip to main content", - configureCore: "Configure OpenAgentCore connection", - coreApi: "Core API", - coreState: "Core API {{state}}", - coreConnecting: "Connecting…", - coreReady: "API ready", - coreFailed: "Failed", theme: "Theme", lightTheme: "Light theme", darkTheme: "Dark theme", language: "Language", english: "English", chinese: "简体中文", - switchToChinese: "Switch to Simplified Chinese", - switchToEnglish: "Switch to English", appearanceSettings: "Language and appearance", } as const; diff --git a/apps/web/src/i18n/locales/en/overview.ts b/apps/web/src/i18n/locales/en/overview.ts index 4ff49d88d..4af9fe201 100644 --- a/apps/web/src/i18n/locales/en/overview.ts +++ b/apps/web/src/i18n/locales/en/overview.ts @@ -81,7 +81,6 @@ export const overview = { attentionSplit: "Last 24 hours: {{failed}} failed, {{waiting}} waiting for caller", }, errors: { - load: "The overview could not be loaded: {{reason}}", summary: "The usage summary could not be loaded: {{reason}}", projects: "Projects could not be loaded: {{reason}}", }, @@ -149,14 +148,7 @@ export const overview = { unavailable: "The usage summary is unavailable.", loading: "Loading usage…", emptyTitle: "No projects yet", - assets: "Assets", sessions: "Sessions", - agents: "Agents", - templates: "Templates", - skills: "Skills", - files: "Files", - vaults: "Vaults", - total: "Total", running: "Running", waiting: "Waiting for caller", failed: "Failed", @@ -181,10 +173,7 @@ export const overview = { emptyOlder: "No Session active in the last 24 hours failed or is waiting for its caller. {{count}} older Sessions need attention in the Session log.", emptyOlder_one: "No Session active in the last 24 hours failed or is waiting for its caller. {{count}} older Session needs attention in the Session log.", emptyOlder_other: "No Session active in the last 24 hours failed or is waiting for its caller. {{count}} older Sessions need attention in the Session log.", session: "Session", status: "Status", - reason: "Reason", lastActive: "Last active", - noError: "No error reported", - requiredActions: "Required actions: {{count}}", }, sessions: { failed: "Failed", diff --git a/apps/web/src/i18n/locales/en/pages.ts b/apps/web/src/i18n/locales/en/pages.ts index 6881cfa99..43224e481 100644 --- a/apps/web/src/i18n/locales/en/pages.ts +++ b/apps/web/src/i18n/locales/en/pages.ts @@ -1,10 +1,6 @@ export const pages = { - dashboard: { - agents: "Agents", sessions: "Sessions", runtime: "Runtime", connectionSettings: "Connection settings", - backend: { label: "OpenAgentCore backend is not ready. Open Docker startup guide", title: "OpenAgentCore backend is not ready", detail: "Web is running, but its local `/v1` proxy cannot reach a ready Core{{failure}}. Start the Docker backend, then test the connection.", openGuide: "Open startup guide", networkFailure: "network failure", collectionFailed: "Collection request failed." }, - }, agents: { title: "Agents", subtitle: "Saved Agents in each project, with their model, Harness, tools and usage." }, sessions: { title: "Sessions", subtitle: "Conversations", recover: "Recover durable state" }, - templates: { title: "Environment Templates", subtitle: "Reusable configuration for managed Sessions.", newTemplate: "New Template" }, - vaults: { title: "Vaults", subtitle: "Core-owned static bearer credentials for exact HTTPS MCP destinations.", refresh: "Refresh Vaults", create: "New Vault" }, + templates: { title: "Environment Templates", subtitle: "Reusable configuration for managed Sessions." }, + vaults: { title: "Vaults", subtitle: "Core-owned static bearer credentials for exact HTTPS MCP destinations.", refresh: "Refresh Vaults" }, } as const; diff --git a/apps/web/src/i18n/locales/en/sessions.ts b/apps/web/src/i18n/locales/en/sessions.ts index 389572f7a..4b6d28689 100644 --- a/apps/web/src/i18n/locales/en/sessions.ts +++ b/apps/web/src/i18n/locales/en/sessions.ts @@ -18,7 +18,7 @@ export const sessions = { sessionStatus: { all: "All", in_progress: "Running", requires_action: "Waiting for caller", failed: "Failed", idle: "Idle", other: "Other" }, environment: { none: "No environment", self_hosted: "Self-hosted", openai_hosted: "Hosted sandbox", other: "Other" }, harness: coreHarnessNames, - usage: { input: "Input", output: "Output", total: "Total", cached: "Cached", reasoning: "Reasoning" }, + usage: { input: "Input", output: "Output", total: "Total" }, log: { title: "Session log", help: "Sessions that callers created with their projects' API keys, most recent activity first. The console reads them and can delete idle ones; open a Session to read its conversation, trace and Turns.", @@ -102,7 +102,6 @@ export const sessions = { noItems: "No Items yet", itemsFailed: "Items could not be loaded: {{reason}}", turnsFailed: "Turns could not be loaded: {{reason}}", - user: "User", error: "Error", unassociated: "Items without a Turn", steps: "{{n}} steps", @@ -120,7 +119,6 @@ export const sessions = { output: "Output", total: "Total tokens", number: "Turn {{number}}", - errorLabel: "Turn error", none: "No Turns yet", }, runtime: { @@ -153,7 +151,6 @@ export const sessions = { status: { never_enrolled: "Never connected", connected: "Connected", disconnected: "Disconnected", revoked: "Bound credential revoked", unknown: "Unknown" }, boundKey: "Bound credential", lastSeen: "Last seen", - notBound: "Not bound", noHeartbeat: "No heartbeat recorded", stale: "Refresh failed. Showing the last loaded binding; the current connection is unknown.", refreshing: "Refreshing the last loaded binding; the current connection is not yet confirmed.", @@ -274,7 +271,7 @@ export const sessions = { trace: { source: "Source", agentSnapshot: "Agent configuration snapshot", itemSnapshot: "Durable Item snapshot", notApplicable: "Not applicable", group: "Group", configuredModel: "Configured model", itemTiming: "Item timing", notProvidedByCore: "Not provided by Core", toolReportedDuration: "Tool-reported duration", turnScopedUsage: "Turn-scoped token usage", turnScopedTokens: "Turn-scoped tokens", scopeBoundary: "This view reports Core resource scope. It does not infer a model span, provider, request step, or subagent relationship.", contractUnavailable: "Unavailable from the current Core contract.", - turnStarted: "Turn started", turnCompleted: "Turn completed", turnWallClock: "Turn wall clock", itemStarted: "Item started", itemCompleted: "Item completed", timingBoundary: "Turn timestamps are server resources. Tool duration has no public absolute start, so it is not positioned on a time-scaled waterfall.", + turnStarted: "Turn started", turnCompleted: "Turn completed", turnWallClock: "Turn wall clock", knownTurnTime: "Known Turn time", turns: "Turns", toolCalls: "Tool calls", search: "Search trace", durableExecutionOrder: "Durable execution order", durableOrder: "Durable order", equalWidth: "Equal-width sequence · not time-scaled", lane: { input: "Input", model: "Model", tools: "Tools" }, label: { system: "SYSTEM", user: "USER", assistant: "ASSISTANT", tool: "TOOL", item: "ITEM" }, openItem: "Open {{label}} trace item: {{title}}", contractNote: "Core reports Turn wall-clock time, but not per-item timing. Rows preserve durable order and are not time-scaled.", loadingHistory: "Loading complete durable Turn and Item history…", @@ -283,30 +280,6 @@ export const sessions = { toolDurationSentence: "Tool-reported duration: {{duration}}.", toolDuration: "Tool-reported duration: {{duration}}", durationUnknown: "Reported duration is unknown.", durationInvalid: "The reported duration could not be interpreted.", perItemNotProvided: "Per-item timing not provided by Core.", perItemTimingMissing: "Core does not provide per-item timing.", turnDuration: "Turn {{duration}}", turnTimeUnknown: "Turn time unknown", turnTimeNotProvided: "Turn time not provided", payloadAvailable: "Payload available", resultAvailable: "Result available", noPreview: "No preview available", configuredInstructions: "Configured instructions", userMessage: "User message", assistantMessage: "Assistant message", unsupportedItem: "Unsupported Item", agentConfiguration: "Agent configuration", turnNumber: "Turn {{number}}", unassociatedItemsNumber: "Unassociated Items {{number}}", unknownCount: "{{count}} unknown", }, - validation: { - absoluteWorkspace: "Workspace directory must be an absolute POSIX path, for example /workspace.", - safeWorkspace: "Workspace directory cannot contain NUL, carriage return, line feed, or backslash characters.", - unsupportedNetworkPolicy: "The managed Environment network policy is unsupported.", - invalidTemplateId: "The selected Environment Template identifier is invalid.", - unsupportedEnvironmentType: "The selected Environment type is unsupported.", - invalidEnvironmentInput: "The Environment input is invalid.", - invalidNoEnvironment: "The no-Environment request contains unsupported fields.", - invalidSelfHosted: "The self-hosted Environment request is not the supported Web profile.", - invalidManaged: "The managed Environment request is not the supported basic profile.", - firstMessageRequired: "A first message is required without an Environment.", - nonblankFirstMessage: "Enter a nonblank first message.", - addUserMessage: "Add at least one user message.", - supportedTextParts: "User message {{number}} must contain supported text parts.", - nonblankTextParts: "User message {{number}} needs nonblank text across its parts.", - atLeastOneTextPart: "User message {{number}} needs at least one text part.", - selectSavedAgent: "Select a saved Agent before configuring Session-only overrides.", - nonemptyModelOverride: "Enter a non-empty Session model override.", - inlineMustNotSendId: "Inline Session creation must not send agent_id.", - invalidInlineProfile: "The inline Agent request is outside the supported Web profile.", - selectLoadedOrInline: "Select a loaded saved Agent or use an inline Agent.", - savedAgentNotLoaded: "The selected saved Agent is not loaded.", - invalidOverrideProfile: "The Session-only Agent override is outside the supported Web profile.", - }, actions: { errors: { metadataConflict: "Metadata changed in OpenAgentCore while you were editing: {{keys}}. Your draft was kept; review the latest values before saving again.", diff --git a/apps/web/src/i18n/locales/en/skills.ts b/apps/web/src/i18n/locales/en/skills.ts index 7ecb4f340..a48a126af 100644 --- a/apps/web/src/i18n/locales/en/skills.ts +++ b/apps/web/src/i18n/locales/en/skills.ts @@ -37,22 +37,14 @@ export const skills = { defaultVersion: "Default version", latestVersion: "Latest version", created: "Created", - id: "ID", newerThanDefault: "Newer than default", newerThanDefaultHelp: "A newer version exists but is not the default. New Sessions keep getting the default version.", noMatchTitle: "No loaded Skill matches", - noMatchDescription: "Only loaded Skills are filtered. Load more or clear the filter.", - loadFailed: "Skills could not be loaded", - refreshFailed: "Refresh failed; the Skills loaded earlier are shown. {{reason}}", moreFailed: "The next page could not be loaded. {{reason}}", }, empty: { title: "No Skills yet", }, - unsupported: { - title: "This Core does not offer Skills", - description: "The connected Core answered the Skill list with {{status}}.", - }, detail: { loading: "Loading Skill…", facts: "Skill details", @@ -81,16 +73,6 @@ export const skills = { downloaded: "Saved {{filename}}", actionFailed: "The request failed. {{reason}}", }, - setDefault: { - title: "Make v{{version}} the default?", - newSessions: "New Sessions that reference this Skill without a version will get v{{version}}.", - existingSessions: "Existing Sessions are not affected.", - metadata: "The Skill's name and description become those of v{{version}}.", - metadataChange: "The Skill's name and description become those of v{{version}}: {{name}}.", - confirm: "Make default", - saving: "Saving…", - done: "v{{version}} is now the default", - }, deleteVersion: { title: "Delete v{{version}}?", body: "Version numbers are never reused. Existing Sessions are not affected.", @@ -113,69 +95,4 @@ export const skills = { deleting: "Deleting…", done: "{{name}} deleted", }, - upload: { - title: "Upload Skill", - versionTitle: "Upload a new version of {{name}}", - source: "Upload from", - zip: "ZIP file", - folder: "Folder", - zipInput: "Choose a ZIP file", - folderInput: "Choose a folder", - reading: "Reading the selection…", - setDefault: "Make this the default version", - setDefaultHelp: "New Sessions that reference the Skill without a version will get this version, and the Skill's name and description will follow it. Existing Sessions are not affected.", - submit: "Upload", - uploading: "Uploading…", - cancelUpload: "Cancel upload", - created: "{{name}} uploaded", - versionCreated: "v{{version}} uploaded", - preview: { - label: "Selection", - folder: "Folder", - files: "Files", - size: "Size", - archive: "ZIP size", - name: "Name", - description: "Description", - missing: "Not found", - }, - requirements: { - title: "Format requirements", - folder: "One top-level folder that contains SKILL.md.", - frontmatter: "SKILL.md frontmatter supports only name, description, license, compatibility and string metadata. Hooks, permission controls and subagent directives are rejected.", - files: "Regular files only: no symbolic links, special files or paths that leave the folder.", - limits: "At most 5 MiB compressed and 20 MiB uncompressed; at most 500 files in a folder upload or 1,000 entries in a ZIP.", - authority: "These are limits of this Core, not of the upstream protocol. Core makes the final check.", - }, - issues: { - noFiles: "The selection has no files.", - tooManyFiles: "{{count}} files exceed the limit of {{limit}}.", - tooLarge: "{{size}} uncompressed exceeds the limit of {{limit}}.", - zipTooLarge: "The ZIP is {{size}}; the limit is {{limit}}.", - notZip: "Choose a file that ends in .zip.", - multipleTopLevel: "Put everything in one top-level folder. Found: {{names}}", - outsideFolder: "These files are outside a folder: {{paths}}", - missingManifest: "{{folder}}/SKILL.md is missing.", - invalidPath: "Unsupported paths: {{paths}}", - duplicatePath: "Duplicate paths: {{paths}}", - hiddenFiles: "Hidden files are uploaded as they are: {{paths}}", - more: "{{list}} and {{count}} more", - manifestUnreadable: "SKILL.md could not be read for the preview.", - zipUnreadable: "This ZIP could not be read for the preview. Core still checks it.", - frontmatterMissing: "SKILL.md does not start with --- frontmatter.", - frontmatterInvalid: "Part of the SKILL.md frontmatter could not be read.", - nameMissing: "The frontmatter has no name.", - descriptionMissing: "The frontmatter has no description.", - unsupportedKeys: "Core rejects these frontmatter fields: {{keys}}", - nameFormat: "Core expects a name of lowercase letters, digits, - and _, at most 64 characters.", - }, - errors: { - invalid: "Core rejected the Skill: {{message}}", - tooLarge: "The files exceed the size limit.", - interrupted: "The upload did not finish. Your selection is kept; Core may have stored it anyway, so check the list before trying again.", - cancelled: "Upload cancelled. Your selection is kept; Core may have stored it anyway, so check the list before trying again.", - other: "The upload failed: {{message}}", - seeRequirements: "Format requirements", - }, - }, } as const; diff --git a/apps/web/src/i18n/locales/en/system.ts b/apps/web/src/i18n/locales/en/system.ts index 1855547f6..cf2f54eeb 100644 --- a/apps/web/src/i18n/locales/en/system.ts +++ b/apps/web/src/i18n/locales/en/system.ts @@ -10,7 +10,6 @@ export const system = { apiBaseUrl: "API base URL", apiBaseUrlHelp: "Applications use it as OPENAI_BASE_URL, with a Project API key as OPENAI_API_KEY.", copyApiBaseUrl: "Copy API base URL", - localOnly: "Only reachable on the Core machine", details: "Installation details", id: "Installation ID", sourceCommit: "Source commit", diff --git a/apps/web/src/i18n/locales/en/templates.ts b/apps/web/src/i18n/locales/en/templates.ts index 1c033e1e2..552f810df 100644 --- a/apps/web/src/i18n/locales/en/templates.ts +++ b/apps/web/src/i18n/locales/en/templates.ts @@ -1,16 +1,11 @@ export const templates = { boundary: "Applications create and change Templates through the Agents API with a project API key. The console only inspects and deletes them.", refreshFailed: "The catalog could not be refreshed. Check the connection and try again.", - savedRefreshFailed: "The change was saved, but the catalog refresh failed. Refresh before making another change.", created: "Template created. No Runtime was allocated.", updated: "Template updated. Existing Sessions keep their configuration.", deleted: "Template deleted.", loading: "Loading Environment Templates…", - unavailableTitle: "Environment Templates are not available", - unavailableDescription: "This Core does not expose the Template resource. No catalog is inferred.", loadFailedTitle: "Environment Templates could not be loaded", - loadFailedDescription: "Check the Core connection and access permissions. The catalog is unavailable.", - configureConnection: "Configure connection", filterLabel: "Filter Templates", filterPlaceholder: "Filter by name or ID", count: "{{visible}} of {{total}} Templates", @@ -24,12 +19,9 @@ export const templates = { }, access: { enabled: "Enabled", disabled: "Disabled", restricted: "Restricted" }, accessHelp: { - enabled: "Native tools can reach any host.", - disabled: "Native tools have no network access.", restricted: "Native tools can reach only the listed hostnames. Subdomains and redirect targets need their own entries.", }, edit: "Edit", - editLabel: "Edit {{name}}", delete: "Delete", deleteLabel: "Delete {{name}}", open: "Open {{name}}", @@ -38,7 +30,7 @@ export const templates = { unrecognizedHelp: "Core returned configuration this console does not recognize. Recognized sections are shown; the others are not guessed.", unrecognizedSections: "Not recognized by this console: {{sections}}", unrecognizedValue: "Not recognized", - modal: { delete: "Delete Template?", edit: "Edit Template", create: "Create Template" }, + modal: { delete: "Delete Template?" }, deletePrompt: "Delete {{name}}?", deleteWarning: "New Sessions can no longer select this Template. Existing Sessions are not affected. This cannot be undone.", deleting: "Deleting…", @@ -97,8 +89,6 @@ export const templates = { saving: "Saving…", saveChanges: "Save changes", create: "Create Template", }, errors: { - forbidden: "Core rejected this request. Check the connection and access permissions.", - missing: "This Template is no longer available. Refresh the catalog before trying again.", invalid: "Core rejected the Template configuration: {{reason}}", uncertain: "The write outcome was not confirmed. Refresh and review Core's catalog before making another change. The request was not replayed.", }, diff --git a/apps/web/src/i18n/locales/en/vaults.ts b/apps/web/src/i18n/locales/en/vaults.ts index f756206c8..f5eb86af5 100644 --- a/apps/web/src/i18n/locales/en/vaults.ts +++ b/apps/web/src/i18n/locales/en/vaults.ts @@ -1,44 +1,19 @@ export const vaults = { securityNote: "Tokens are write only. This page receives Credential metadata, never token values. Deleting a Vault also deletes all of its stored Credentials and does not revoke provider-side tokens.", - actionNotConfirmed: "Action not confirmed", - mutationUncertain: "The write outcome was not confirmed. The catalog was refreshed; review current Core state before explicitly trying again.", loading: "Loading Vaults", loadFailed: "Couldn’t load Vaults", refreshFailed: "Couldn’t refresh Vaults", - failedDescription: "The Web could not load the complete Vault and Credential catalog.", staleDescription: "The previous safe metadata snapshot remains visible, but it cannot authorize new Sessions.", - failedHint: "Check the Core connection, then refresh. Credentialed Sessions stay blocked until the complete catalog loads.", credential: "Credential", deleteVaultLabel: "Delete {{name}}", created: "Created", credentialsIn: "Credentials in {{name}}", - updatedHidden: "Updated {{date}} · token hidden", oauthHelp: "OAuth · Manage authorization and token replacement in your application.", - replaceTokenLabel: "Replace token for {{name}}", replaceToken: "Replace token", deleteCredentialLabel: "Delete {{name}}", + oauthHelp: "OAuth · Manage authorization and token replacement in your application.", + deleteCredentialLabel: "Delete {{name}}", noCredentials: "No Credentials in this Vault.", noVaults: "No Vaults yet", - createVault: "Create Vault", createVaultTitle: "Create a Vault", deleteVaultTitle: "Delete Vault?", deleteCredentialTitle: "Delete Credential?", + deleteVaultTitle: "Delete Vault?", deleteCredentialTitle: "Delete Credential?", deleting: "Deleting…", delete: "Delete", deleteVaultPrompt: "Delete {{name}} and all of its stored Credentials? Existing Sessions keep frozen IDs, but later secret lookup fails. Provider tokens and running work are not revoked.", deleteCredentialPrompt: "Delete {{name}}? Existing Sessions keep its frozen identity, but later secret lookup fails. This does not revoke the token at the MCP provider.", unnamed: "Unnamed Vault", - list: { label: "Vaults", filterLabel: "Filter Vaults", filterPlaceholder: "Filter by name or ID", name: "Name", credentials: "Credentials", created: "Created", actions: "Actions", open: "Open {{name}}", noMatch: "No matching Vaults" }, + list: { label: "Vaults", filterLabel: "Filter Vaults", filterPlaceholder: "Filter by name or ID", name: "Name", created: "Created", actions: "Actions", open: "Open {{name}}", noMatch: "No matching Vaults" }, detail: { back: "Back", facts: "Vault details", id: "ID", created: "Created", metadata: "Metadata", credentials: "Credentials", credentialsHelp: "Static bearer tokens are write-only: Core never returns them, so this page shows metadata only. Replacing a token does not revoke the old one at the provider.", name: "Name", url: "MCP server URL", auth: "Authentication", updated: "Updated", addCredential: "Add Credential", deleteVault: "Delete Vault", staticBearer: "Static bearer", oauth: "OAuth", tokenHidden: "Token hidden" }, - createForm: { - name: "Name", namePlaceholder: "Runtime credentials", nameHelp: "Required. The trimmed name may contain at most 256 UTF-8 bytes.", - metadata: "Metadata", optional: "Optional", metadataHelp: "Enter a JSON object with string values. Blank input becomes {{emptyObject}}; encoded metadata may be at most 64 KiB.", - metadataWarning: "Vault metadata is public. Never place secrets, tokens, passwords, credentials, or private connection data here.", - creating: "Creating…", create: "Create Vault", - }, - credentialDialog: { - replaceTitle: "Replace token · {{name}}", addTitle: "Add static bearer Credential", saving: "Saving…", create: "Create Credential", - notConfirmed: "Credential was not confirmed", name: "Name", namePlaceholder: "Internal MCP", exactUrl: "Exact MCP server URL", - urlHelp: "The URL must exactly match the Agent MCP definition. Creating this resource makes no network request.", - replaceWarning: "The old token is never read or shown. Running work may already hold it, and replacing it does not revoke the provider-side token.", - newToken: "New bearer token", token: "Bearer token", tokenHelp: "Write only. It is sent once, immediately cleared, and never stored in browser state, metadata, previews, or logs.", - }, errors: { - auth: "Core authentication failed. The Credential was not confirmed.", missing: "The Vault or Credential is no longer available. Refresh before trying again.", - tooLarge: "The Credential request exceeded Core's accepted size.", invalidFields: "Core rejected the Credential fields. Check the name, exact HTTPS URL, and token format.", - credentialUncertain: "The Credential write outcome was not confirmed. The catalog was refreshed; review it before explicitly trying again.", - bearer: "Enter a non-empty RFC 6750 bearer token. Whitespace and other opaque storage-only values cannot execute in the current runtime.", - credentialName: "Credential name must contain 1 to 256 UTF-8 bytes.", exactUrl: "Enter an exact HTTPS MCP URL without credentials, query parameters, fragments, whitespace, or backslashes.", - createUncertain: "Vault creation was not confirmed. Your draft is unchanged. Review current Core state before explicitly trying again.", - vaultName: "Name must contain 1 to 256 UTF-8 bytes.", metadataUnknown: "Metadata could not be validated.", metadataJson: "Metadata must be valid JSON.", - metadataShape: "Metadata must be a JSON object whose values are strings.", metadataStrings: "Metadata values must all be strings; nested values, arrays, numbers, booleans, and null are not supported.", - metadataLarge: "Metadata must be at most 64 KiB after UTF-8 JSON encoding.", mismatchedMetadata: "OpenAgentCore returned mismatched Vault metadata.", + tooLarge: "The Credential request exceeded Core's accepted size.", uniqueAttachments: "Vault attachments must be unique.", catalogIncomplete: "Credential metadata is not fully loaded from this Core.", vaultMissing: "A selected Vault is no longer available in the current catalog.", credentialMismatch: "MCP server {{server}} references an unavailable or URL-mismatched Credential.", credentialVaultMissing: "MCP server {{server}} references a Credential whose Vault is unavailable.", multipleCredentials: "Anonymous MCP server {{server}} matches multiple Credentials in the selected Vaults. Select a single matching Vault or configure one Credential explicitly.", matchedVaultMissing: "MCP server {{server}} matched a Credential whose Vault is unavailable.", diff --git a/apps/web/src/i18n/locales/zh-CN/agents.ts b/apps/web/src/i18n/locales/zh-CN/agents.ts index 9cc0aedf9..074b79c71 100644 --- a/apps/web/src/i18n/locales/zh-CN/agents.ts +++ b/apps/web/src/i18n/locales/zh-CN/agents.ts @@ -1,14 +1,11 @@ import type { agents as english } from "../en/agents"; type TranslationShape = { [K in keyof T]: T[K] extends string ? string : TranslationShape }; export const agents: TranslationShape = { - loading: "正在加载 Agent", requestFailed: "OpenAgentCore 请求失败。", searchPlaceholder: "按名称、模型或 ID 搜索…", filtersLabel: "Agent 筛选", searchLabel: "搜索 Agent", refreshLabel: "刷新 Agent", loadFailed: "无法加载 Agent", refreshFailed: "无法刷新 Agent", staleDescription: "上次加载的 Agent 配置仍然可用。", loadDescription: "Web 无法从已连接的 OpenAgentCore 读取 Agent 配置。", connectionHint: "请检查侧栏中的 OpenAgentCore 连接后重试。", openFailed: "无法打开最新 Agent", retry: "重试", requestFailure: "请求失败", - errors: { - retrievalUnavailable: "此 OpenAgentCore 连接不支持读取 Agent。", interrupted: "Agent 请求因连接变化而中断。", differentRetrieved: "OpenAgentCore 返回了与请求不同的 Agent。", updateUnavailable: "此 OpenAgentCore 连接不支持更新 Agent。", updateInterrupted: "Agent 更新因连接变化而中断。", differentUpdated: "OpenAgentCore 返回了与所更新对象不同的 Agent。", deleteUnavailable: "此 OpenAgentCore 连接不支持删除。", modelRequired: "请输入模型 ID。", nameTooLong: "名称最多 128 个字符。", metadataJson: "元数据必须是有效 JSON。", metadataObject: "元数据必须是 JSON 对象。", metadataStrings: "每个元数据值都必须是字符串。", metadataCount: "Agent 元数据最多支持 16 组键值。", metadataLength: "元数据键最多 64 个字符,值最多 512 个字符。", reasoningDefault: "当前 Core Session 要求两个推理字段都使用 Core 默认值。", serviceTier: "当前 Core Session 仅支持 auto 服务层级。", textFormat: "当前 Core Session 仅支持文本格式。", verbosity: "低或高详细程度需要已发现的兼容 Codex 模型;此 Web 流程请使用 medium。", readOnlyTools: "此 Agent 包含只读的已保存工具定义,因此不能更改工具。", functionName: "每个 Function 都需要非空名称。", functionNameLength: "Function 名称最多 512 个 UTF-8 字节。", functionUnique: "Function 名称不能重复。", functionJson: "Function {{name}} 的参数必须是有效 JSON。", functionSchema: "Function {{name}} 的参数必须是 JSON 对象 schema。", mcpLabel: "每个 MCP 服务都需要非空标签。", mcpUnique: "MCP 服务标签不能重复。", mcpUrl: "MCP 服务 {{name}} 需要有效的匿名 HTTP(S) URL。", credentialMissing: "MCP 服务 {{name}} 引用了当前目录中不存在的 Credential。", credentialUrl: "MCP 服务 {{name}} 必须使用所选 Credential 的精确 URL。", functionCount: "最多可配置 64 个 Function。", - }, + loading: "正在加载 Agent", searchPlaceholder: "按名称、模型或 ID 搜索…", refreshLabel: "刷新 Agent", loadFailed: "无法加载 Agent", refreshFailed: "无法刷新 Agent", retry: "重试", view: { filterLabel: "筛选 Agent", searchPlaceholder: "按名称、模型或 ID 搜索", - columns: { agent: "Agent", model: "模型", harness: "Harness", tools: "工具", sessions: "Session", tokens: "Token", lastActive: "最近活跃", updated: "更新时间", actions: "操作" }, + columns: { agent: "Agent", model: "模型", harness: "Harness", tools: "工具", sessions: "Session", tokens: "Token", lastActive: "最近活跃", actions: "操作" }, open: "打开 {{name}}", coreDefault: "Core 默认", back: "返回", @@ -56,25 +53,9 @@ export const agents: TranslationShape = { delete: "删除", }, catalog: { - listLabel: "Agent", create: "创建 Agent", untitled: "未命名 Agent", editLabel: "编辑 {{name}}({{id}})", opening: "正在打开最新定义…", startLabel: "使用 {{name}}({{id}})启动 Session", unavailable: "不可用", startSession: "启动 Session", sessionUnavailable: "Session 不可用:{{reason}}", noMatch: "没有匹配的 Agent", noSaved: "还没有 Agent", clearSearch: "清除搜索", - columns: { agent: "Agent", model: "模型", harness: "Harness", tools: "工具", updated: "更新时间", actions: "操作" }, coreDefaultHarness: "Core 默认", copyId: "复制 Agent ID {{id}}", copied: "已复制", unavailableHelp: "无法启动 Session 的原因", + listLabel: "Agent", untitled: "未命名 Agent", noMatch: "没有匹配的 Agent", noSaved: "还没有 Agent", }, details: { - id: "ID", created: "创建时间", updated: "更新时间", model: "模型", name: "名称", instructions: "指令", metadata: "元数据", notSet: "未设置", none: "无", blocked: "此 Agent 可以保存,但已知的 Core Session 配置无法启动它:{{reason}}", runtimeBoundary: "已保存的高级配置不能证明运行时可用。模型、provider、主机、工具和条件性详细程度仍需 executor 验证。", advanced: "高级配置 · 只读", tools: "工具", reasoning: "推理", text: "文本", serviceTier: "服务层级", multiAgent: "多 Agent", functionTool: "Function {{name}}", mcpTool: "{{auth}} 服务来源 HTTP MCP {{name}}", serviceOriginMcp: "服务来源 HTTP MCP", vaultBearer: "Vault bearer", anonymous: "匿名", readOnly: "{{label}} · 只读", deletePrompt: "从 OpenAgentCore 删除 {{name}}?", deleteBefore: "从 OpenAgentCore 删除", deleteAfter: "?", exactId: "精确 Agent ID:{{id}}", exactIdLabel: "精确 Agent ID:", deleteWarning: "只有在 Core 确认成功后才会移除已保存的 Agent。现有 Session 会保留持久化的 Agent 快照。", deleteTitle: "删除 Agent?", cancel: "取消", deleting: "删除中…", - }, - savedTool: { malformed: "已保存的工具定义格式错误", toolSearch: "tool_search 仅可保存,不能在 Session 中运行", programmatic: "programmatic_tool_calling 仅可保存,不能在 Session 中运行", webSearchDisabled: "已禁用的 web_search 在 Web 中仅可查看;Session 将保持搜索关闭", webSearchEnabled: "已启用的 web_search 仅可保存;Core 不会在 Session 中运行已启用的搜索", deferred: "延迟 Function 仅可保存", credentialedMcp: "当前 Vault 目录中无法解析需要 Credential 的 MCP,或其 URL 不匹配", unsupportedFunction: "不支持的 Function 工具定义", unsupportedMcp: "不支持的 MCP 工具定义", unsupported: "不支持的已保存工具定义" }, - admission: { model: "模型不能为空", multiAgent: "不支持多 Agent 执行", reasoning: "显式推理选项仅可保存", serviceTier: "服务层级必须为 auto", text: "文本格式必须为 text", malformedTool: "已保存的工具配置不可执行", malformedFunction: "已保存的 Function 工具不完整或格式错误", deferred: "延迟 Function 仅可保存", functionName: "Function 名称必须非空且最多 512 字节", functionUnique: "Function 名称必须唯一", malformedMcp: "已保存的 MCP 工具不完整或格式错误", credential: "此 Web Session 流程无法使用附加的 MCP Credential", mcpUnique: "MCP 服务标签必须唯一", malformedWebSearch: "已保存的 web_search 工具不完整或格式错误", enabledWebSearch: "web_search 模式必须禁用,因为 Core 不会运行已启用的搜索", savedOnly: "{{type}} 仅可保存", unsupportedTool: "已保存的工具类型不可执行", functionCount: "最多可执行 64 个 Function 工具", webSearchCount: "最多可执行一个 web_search 工具", coreRequires: "当前 Core Session 准入要求:{{reasons}}。", vaultUnavailable: "无法附加 Session Vault。{{reason}}", managedMcp: "托管 Session 暂不支持 MCP 工具。请选择无环境或自托管环境,或使用仅含 Function 的 Agent。" }, - usage: { - title: "用量", rangeLabel: "Session 创建时间", ranges: { all: "全部", "7d": "近 7 天", "30d": "近 30 天" }, - help: "用量是 Core 报告的每个 Session 的累计值,不按天拆分。Session 按创建时间归入时间范围,其全部用量都计入该范围。", - caveat: "数据来自 Core 报告的 Session 累计用量,不包含未报告的部分,不能作为计费依据。", - reading: "正在读取 Session…已读取 {{formattedCount}} 个", cancel: "取消", cancelled_one: "已在读取 {{formattedCount}} 个 Session 后停止。", cancelled_other: "已在读取 {{formattedCount}} 个 Session 后停止。", continue: "继续", failed: "无法读取 Session。", retry: "重试", - large: "Session 超过 {{formattedCount}} 个,统计可能较慢。建议先缩小时间范围。", largeShortest: "Session 超过 {{formattedCount}} 个,统计可能较慢。", - sessions: "Session", tokens: "Token", coverage: "覆盖率", lastActive: "最近活跃", noData: "无数据", cardLabel: "{{name}} 的用量", - coverageHelp: "Core 报告了用量的 Session 占范围内全部 Session 的比例。没有报告用量的 Session 不计入 Token 合计,也不按 0 计算。", - coverageDetail_one: "{{formattedCount}} 个 Session 中有 {{reported}} 个报告了用量", coverageDetail_other: "{{formattedCount}} 个 Session 中有 {{reported}} 个报告了用量", - status: "状态", statuses: { in_progress: "进行中", requires_action: "需要处理", failed: "失败", idle: "空闲", unknown: "无法识别" }, - tokenKinds: { input: "输入", output: "输出", total: "总计", cached: "缓存命中", reasoning: "推理" }, - other: { title: "其他 Agent", help: "这些 Session 的 Agent ID 不在当前 Agent 列表中:Agent 可能已被删除,或创建 Session 时使用了内联配置。按原始 Agent ID 分组。", agentId: "Agent ID", missingId: "无 Agent ID", showAll: "显示全部 {{formattedCount}} 个", showLess: "收起" }, + reasoning: "推理", }, }; diff --git a/apps/web/src/i18n/locales/zh-CN/common.ts b/apps/web/src/i18n/locales/zh-CN/common.ts index 19b551883..33e750769 100644 --- a/apps/web/src/i18n/locales/zh-CN/common.ts +++ b/apps/web/src/i18n/locales/zh-CN/common.ts @@ -71,6 +71,5 @@ export const common = { loadedMore: "已加载 {{n}} 个,还有更多", noMatches: "没有匹配项", deleteUncertain: "未能确认删除结果,Core 可能已删除,也可能没有。页面已重新读取,请先确认再决定是否重试。", - noMatchesDescription: "没有符合当前搜索或筛选条件的结果。", }, } as const; diff --git a/apps/web/src/i18n/locales/zh-CN/dashboard.ts b/apps/web/src/i18n/locales/zh-CN/dashboard.ts deleted file mode 100644 index 230514d60..000000000 --- a/apps/web/src/i18n/locales/zh-CN/dashboard.ts +++ /dev/null @@ -1,20 +0,0 @@ -export const dashboard = { - trends: { - title: "资源趋势", retained: "保留采样 · 持久历史", local: "浏览器本地采样 · 重新加载后重置", source: "运行时指标数据源", live: "实时", history: "历史", - historyStale: "历史数据已过期", historyLoading: "历史 · 加载中", durableResolution: "持久数据 · {{seconds}}秒", liveRetrying: "实时 · 正在重试历史数据", liveUnavailable: "实时 · 历史数据不可用", liveLoading: "实时 · 正在加载历史数据", staleRetrying: "已过期 · 正在重试", liveInterval: "实时 · {{seconds}}秒", - durableStatus: "{{status}};{{count}} 个 运行时目标", retainedFailure: "运行时采样刷新失败,正在显示保留采样", samplingInterval: "运行时每 {{seconds}} 秒实时采样一次", - bucket: "时间桶", buckets: "时间桶", sample: "个采样", samples: "个采样", observations: "{{actual}}/{{expected}} 个观测", durableRange: "运行时持久时间范围", liveRange: "运行时实时时间范围", - refreshFailed: "持久历史刷新失败:{{error}}", notConfigured: "未配置持久历史;实时采样仍可用。", requestFailed: "请求 运行时持久历史失败。", - }, - charts: { - collecting: "正在收集实时采样", durableHistory: "持久历史", live: "实时", retainedBuckets: "保留时间桶", liveSamples: "实时采样", chartLabel: "{{title}} {{source}} 图表", - hideSeries: "隐藏 {{series}} 序列", showSeries: "显示 {{series}} 序列", hide: "隐藏 {{series}}", show: "显示 {{series}}", resetZoom: "重置缩放", - instructions: "将指针移到图表上可查看精确值。水平拖动可选择并缩放时间范围。双击或使用“重置缩放”可恢复完整范围。单击可固定时间点,使用左右方向键移动,按 Esc 清除。", - pinned: "已固定", hover: "悬停", unavailable: "不可用", allHidden: "已隐藏所有序列", sparse: "采样稀疏", showLegend: "使用图例显示序列", sparseDetail: "{{count}} 个有效点 · 绘制连线需要连续时间桶", emptyDetail: "{{valid}}/2 个有效点 · {{count}} 个快照 · 不会合成历史数据", - table: { series: "序列", latest: "最新值", missing: "缺失采样" }, runtime: "运行时", usage: "使用率", used: "已使用", configuredLimit: "配置上限", input: "输入", output: "输出", gridDurable: "运行时持久历史图表", gridLive: "运行时实时窗口图表", - cpu: { title: "CPU 使用率", withoutData: "{{count}} 个运行时目标在此时间段内没有 CPU 数据", durable: "按时间桶聚合的累计差值使用率 · 持久历史", live: "已报告或累计差值使用率 · 实时窗口", empty: "无保留的 CPU 采样" }, - memory: { title: "内存使用", durable: "已观测沙箱 聚合 / 配置上限 · 持久历史", live: "已观测沙箱 工作集 / 配置上限 · 实时窗口", empty: "无保留的已观测内存采样" }, - active: { series: "活跃", sandboxTitle: "活跃沙箱", runtimeTitle: "运行时活跃状态", sumDurable: "每个保留时间桶中的已观测分配数 · 持久历史", sumLive: "每个快照中生命周期状态为活动的分配数 · 实时窗口", binaryDurable: "保留时间桶中存在已观测分配 · 1 活动 / 0 非活跃", binaryLive: "生命周期状态为活动 · 1 活动 / 0 非活跃", active: "活跃", inactive: "非活跃", empty: "无保留的活跃沙箱 采样" }, - tokens: { title: "Token 吞吐量", durable: "规范 Session 用量差值 · 持久历史", live: "Session 用量差值 · 排除缺失用量", empty: "无保留的 Token 采样", perMinute: "{{value}}/分钟" }, - }, -} as const; diff --git a/apps/web/src/i18n/locales/zh-CN/files.ts b/apps/web/src/i18n/locales/zh-CN/files.ts index 5bff5e584..945e6a3a2 100644 --- a/apps/web/src/i18n/locales/zh-CN/files.ts +++ b/apps/web/src/i18n/locales/zh-CN/files.ts @@ -35,37 +35,20 @@ export const files: TranslationShape = { size: "大小", created: "创建时间", purpose: "Purpose", - id: "File ID", actions: "操作", exactBytes: "{{bytes}} 字节", unrecognized: "无法识别的文件", unrecognizedHelp: "Core 返回了控制台无法识别的元数据,因此只显示 File ID。", noMatchTitle: "没有匹配的已加载文件", - noMatchDescription: "筛选只作用于已加载的文件。请加载更多或清除筛选。", - loadFailed: "无法加载文件", - refreshFailed: "列表刷新失败:{{reason}}", moreFailed: "无法加载更多文件:{{reason}}", }, empty: { title: "还没有文件", }, - unsupported: { - title: "此 Core 不支持列出文件", - description: "文件列表请求返回 HTTP {{status}}。", - }, - upload: { - uploading: "正在上传 {{name}}…", - uploaded: "已上传 {{name}}", - tooLarge: "{{name}} 超过 512 MiB 上传上限。", - badName: "文件名须为 1–1024 个 UTF-8 字节,且不能包含 NUL 字符。", - rejected: "Core 拒绝上传 {{name}}:{{reason}}", - uncertain: "{{name}} 可能已上传到 Core。请先刷新列表确认,再决定是否重新上传。", - }, delete: { prompt: "删除 {{name}}?", consequences: "已复制到 Session 工作区的副本不受影响,已创建的 Session 也不受影响。通过 File ID 引用此文件的环境模板,之后再新建 Session 会失败。", deleted: "已删除 {{name}}", - missing: "{{name}} 已被删除。", rejected: "Core 拒绝删除:{{reason}}", uncertain: "未能确认 {{name}} 是否已删除。请先刷新列表确认,再决定是否重试。", }, diff --git a/apps/web/src/i18n/locales/zh-CN/navigation.ts b/apps/web/src/i18n/locales/zh-CN/navigation.ts index 55afa7f55..112b56743 100644 --- a/apps/web/src/i18n/locales/zh-CN/navigation.ts +++ b/apps/web/src/i18n/locales/zh-CN/navigation.ts @@ -27,19 +27,11 @@ export const navigation = { settings: {"sandbox": "沙箱与调度", "storage": "工作区存储", "models": "模型与凭据", "service": "服务与部署"}, showGettingStarted: "显示新手引导", skipToContent: "跳到主要内容", - configureCore: "配置 OpenAgentCore 连接", - coreApi: "Core API", - coreState: "Core API {{state}}", - coreConnecting: "连接中…", - coreReady: "API 已就绪", - coreFailed: "失败", theme: "主题", lightTheme: "浅色主题", darkTheme: "深色主题", language: "语言", english: "English", chinese: "简体中文", - switchToChinese: "切换到简体中文", - switchToEnglish: "切换到英文", appearanceSettings: "语言和外观", } as const; diff --git a/apps/web/src/i18n/locales/zh-CN/overview.ts b/apps/web/src/i18n/locales/zh-CN/overview.ts index 567f83d28..48da834f0 100644 --- a/apps/web/src/i18n/locales/zh-CN/overview.ts +++ b/apps/web/src/i18n/locales/zh-CN/overview.ts @@ -81,7 +81,6 @@ export const overview = { attentionSplit: "过去 24 小时:失败 {{failed}},等待调用方 {{waiting}}", }, errors: { - load: "无法加载概览:{{reason}}", summary: "无法加载用量汇总:{{reason}}", projects: "无法加载项目:{{reason}}", }, @@ -149,14 +148,7 @@ export const overview = { unavailable: "用量汇总不可用。", loading: "正在加载用量…", emptyTitle: "还没有项目", - assets: "资产", sessions: "Session", - agents: "Agent", - templates: "环境模板", - skills: "Skills", - files: "文件", - vaults: "Vault", - total: "总数", running: "运行中", waiting: "等待调用方", failed: "失败", @@ -181,10 +173,7 @@ export const overview = { emptyOlder: "过去 24 小时内活跃的 Session 都没有失败或等待调用方。Session 日志中还有 {{count}} 个更早的 Session 需要处理。", emptyOlder_one: "过去 24 小时内活跃的 Session 都没有失败或等待调用方。Session 日志中还有 {{count}} 个更早的 Session 需要处理。", emptyOlder_other: "过去 24 小时内活跃的 Session 都没有失败或等待调用方。Session 日志中还有 {{count}} 个更早的 Session 需要处理。", session: "Session", status: "状态", - reason: "原因", lastActive: "最近活跃", - noError: "未上报错误信息", - requiredActions: "待完成操作:{{count}}", }, sessions: { failed: "失败", diff --git a/apps/web/src/i18n/locales/zh-CN/pages.ts b/apps/web/src/i18n/locales/zh-CN/pages.ts index a1b45e879..43282b923 100644 --- a/apps/web/src/i18n/locales/zh-CN/pages.ts +++ b/apps/web/src/i18n/locales/zh-CN/pages.ts @@ -1,10 +1,6 @@ export const pages = { - dashboard: { - agents: "Agent", sessions: "Session", runtime: "运行时", connectionSettings: "连接设置", - backend: { label: "OpenAgentCore 后端未就绪。打开 Docker 启动指南", title: "OpenAgentCore 后端未就绪", detail: "Web 正在运行,但本地 /v1 代理无法连接已就绪的 Core{{failure}}。请启动 Docker 后端,然后测试连接。", openGuide: "打开启动指南", networkFailure: "网络故障", collectionFailed: "数据收集请求失败。" }, - }, agents: { title: "Agent", subtitle: "各项目保存的 Agent,及其模型、Harness、工具和用量。" }, sessions: { title: "Session", subtitle: "对话", recover: "恢复持久状态" }, - templates: { title: "环境模板", subtitle: "用于托管 Session 的可复用配置。", newTemplate: "新建模板" }, - vaults: { title: "Vault", subtitle: "由 Core 管理、仅用于精确 HTTPS MCP 目标的静态 bearer Credential。", refresh: "刷新 Vault", create: "新建 Vault" }, + templates: { title: "环境模板", subtitle: "用于托管 Session 的可复用配置。" }, + vaults: { title: "Vault", subtitle: "由 Core 管理、仅用于精确 HTTPS MCP 目标的静态 bearer Credential。", refresh: "刷新 Vault" }, } as const; diff --git a/apps/web/src/i18n/locales/zh-CN/sandbox.ts b/apps/web/src/i18n/locales/zh-CN/sandbox.ts index 8c097db53..d5ba0a075 100644 --- a/apps/web/src/i18n/locales/zh-CN/sandbox.ts +++ b/apps/web/src/i18n/locales/zh-CN/sandbox.ts @@ -65,10 +65,6 @@ export const sandbox = { "Leave blank to keep the saved key. Any key you enter is verified as a replacement, even if unchanged.": "留空可保留已保存的密钥。填写的密钥都会作为替换密钥进行验证,即使内容未变。", "These limits apply to the selected configuration generation. Existing sandboxes keep their limits. Concurrency is set per node.": "这些限制适用于所选配置代次。现有沙箱保留原有限制。并发数量按节点设置。", "The target Runtime release. Existing sandboxes keep their owned release while nodes prepare the target.": "目标 Runtime 版本。节点准备目标版本时,现有沙箱仍使用其所属版本。", - "This E2B key cannot manage the retained deployment. Reset before changing teams.": "此 E2B 密钥无法管理当前保留的部署。更换团队前请先重置。", - "The E2B API key was rejected. The saved configuration is unchanged.": "E2B API 密钥被拒绝。已保存的配置未改变。", - "Select a ready immutable E2B template build with matching resources.": "请选择已就绪且资源匹配的不可变 E2B 模板构建。", - "E2B verification could not be confirmed. Refresh before submitting again.": "无法确认 E2B 验证结果。请刷新后再提交。", "Cancel editing to use Reset deployment. This change requires an explicit reset; the saved configuration is unchanged.": "取消编辑后可使用“重置部署”。此更改需要明确重置;已保存的配置未改变。", "Sandbox state is unconfirmed. Refresh before issuing a node command.": "沙箱状态尚未确认。请刷新后再生成节点命令。", @@ -101,21 +97,13 @@ export const sandbox = { "Clear hosted work": "清理托管任务", "Auto — let busy work finish": "自动 — 等待忙碌任务完成", "Idle, suspended and queued Sessions are archived immediately. Running or waiting Turns and file writes may finish until the deadline; then Core forces the rest.": "空闲、挂起和排队中的 Session 会立即归档。运行中或等待中的 Turn 及文件写入可在截止时间前继续;之后 Core 会强制清理剩余任务。", - "Force remaining work after (seconds)": "多久后强制清理剩余任务(秒)", "Default: 1 hour. Choose a whole number from 300 to 86400 seconds (5 minutes to 24 hours).": "默认 1 小时。请输入 300 到 86400 秒之间的整数(5 分钟到 24 小时)。", "Enter a whole number from 300 to 86400 seconds.": "请输入 300 到 86400 秒之间的整数。", "Force — cancel remaining work now": "强制 — 立即取消剩余任务", "Sandbox state changed. Close this dialog and review the current state.": "沙箱状态已改变。请关闭对话框并查看当前状态。", "Node state could not be read": "无法读取节点状态", "Node enrollment is paused while reset is in progress.": "重置过程中暂停注册节点。", - "Unsaved workspace contents may be lost.": "尚未保存的工作区内容可能丢失。", - "Core has a newer sandbox configuration. Refresh and review it before submitting again.": "Core 的沙箱配置已更新。请刷新并检查后再提交。", "Reset the sandbox deployment before changing this configuration.": "请先重置沙箱部署,再更改此配置。", - "A sandbox reset is in progress. Refresh to see its current progress.": "沙箱正在重置。请刷新查看当前进度。", - "The sandbox deployment is not configured. Refresh to start setup.": "沙箱部署尚未配置。请刷新以开始配置。", - "Hosted resources remain. Wait for confirmed cleanup before changing the configuration.": "仍有托管资源。请等待 Core 确认清理完成后再修改配置。", - "Change provider or resources": "修改运行后端或资源", - "Sandbox backend": "沙箱后端", "Core records these sandboxes as suspended. Their next Turn requests a resume when compatible capacity is available. They count toward the retained limit, not the active one.": "Core 将这些沙箱记录为已挂起。下一个 Turn 会在兼容容量可用时请求恢复。它们占用保留名额,不占活跃名额。", "The most sandboxes this node holds at once: starting, running and suspended.": "这台节点同时最多容纳的沙箱数,包括启动中、运行中和已挂起的。", "Edit node": "编辑节点", @@ -129,9 +117,6 @@ export const sandbox = { "Enter a shorter name.": "名称太长了,请缩短。", "Enter a whole number from 1 to 1,000,000.": "请输入 1 到 1,000,000 之间的整数。", "Enter at least the number of sandboxes at once.": "不能少于同时运行的沙箱数。", - "E2B runs this deployment's sandboxes in its cloud. There are no machines to add.": "这个部署的沙箱由 E2B 在云端运行,不需要添加机器。", - "Saving does not migrate Sessions or resume placement automatically.": "保存不会迁移 Session,也不会自动恢复分配。", - "Use an HTTPS Core origin reachable from every node and sandbox guest, without a path or credentials. The console URL may be different.": "请输入所有节点和沙箱都能访问的 HTTPS Core 源地址,不含路径或凭据。此地址可能与控制台地址不同。", "Needs attention": "需要检查", "Done": "完成", "Copy command": "复制命令", @@ -202,11 +187,6 @@ export const sandbox = { "The node registered but its service hasn't reached Core.": "节点已注册,但节点服务还没有连上 Core。", "The node service keeps retrying while Core is unavailable, and stops once the node is removed.": "Core 不可用时,节点服务会一直重试;节点被移除后才会停止。", "Check the log on the host:": "在主机上查看日志:", - "Advanced network settings": "高级网络设置", - - "System": "系统", - "System navigation": "系统导航", - "Deployment provider, runtime nodes and Session allocations.": "管理部署后端、运行节点和 Session 资源分配。", "Refresh sandbox state": "刷新沙箱状态", "Loading sandbox state…": "正在加载沙箱状态…", "Provider": "运行后端", @@ -237,7 +217,6 @@ export const sandbox = { "Recorded state": "已记录状态", "Recorded compute": "已记录计算状态", "In this state": "当前状态持续", - "Since {{time}}": "{{time}}起", "No sandbox allocations.": "暂无沙箱资源分配。", "Add node": "添加节点", "One-time enrollment command": "一次性注册命令", @@ -247,25 +226,10 @@ export const sandbox = { "Never": "尚无记录", "Unavailable": "不可用", "Available": "可用", - "Sandbox node": "沙箱节点", - "Automatic placement": "自动分配", "available": "可用", "unavailable": "不可用", - "Loading nodes…": "正在加载节点…", - "Retry directory": "重新加载节点目录", - "No nodes are registered.": "尚未注册节点。", - "Node directory unavailable. Automatic placement remains available; an explicit choice is never replaced automatically.": "节点目录不可用。仍可使用自动分配;明确选择的节点不会被自动替换。", - "Loading placement…": "正在加载分配信息…", - "Recorded allocation": "已记录分配状态", - "Refresh placement": "刷新分配信息", - "No hosted placement": "无托管分配", - "Retry placement": "重新加载分配信息", - "Sandbox placement could not be loaded.": "无法加载沙箱分配信息。", "The sandbox request failed. Refresh to check the current state before trying again.": "沙箱请求失败。重试前请刷新并检查当前状态。", "Core did not confirm node removal. Refresh to check its state.": "Core 未确认节点已移除。请刷新以检查状态。", - "The node has active allocations or retained resources. Clear allocations, snapshots, reservations and pending cleanup before removal.": "节点仍有活跃分配或保留资源。请先清理资源分配、快照、预留资源和待清理项,再移除节点。", - "The selected sandbox node is unavailable or has no capacity.": "所选沙箱节点不可用或容量不足。", - "Sign in to the console again to access sandbox management.": "请重新登录控制台以访问沙箱管理。", "Core rejected the sandbox change": "Core 拒绝了此次沙箱更改", "Core rejected the sandbox configuration.": "Core 拒绝了这个沙箱配置。", "The console configuration could not be read. Refresh to try again.": "无法读取控制台配置。请刷新重试。", @@ -311,17 +275,9 @@ export const sandbox = { "The host has less CPU or memory than one sandbox needs. Use a bigger host or a smaller sandbox size.": "主机的 CPU 或内存不够运行一个沙箱。请换一台更大的主机,或调小沙箱规格。", "Connecting to this console's Core…": "正在连接此控制台的 Core…", "Saving sandbox change…": "正在保存沙箱更改…", - "Refresh sandbox state to confirm whether setup was saved before submitting again.": "再次提交前,请刷新沙箱状态以确认配置是否已保存。", "Set up hosted sandboxes": "配置托管沙箱", - "Sandbox provider": "沙箱后端", - "Choose a provider": "选择运行后端", - "Core origin reachable from nodes and guests": "节点和沙箱可访问的 Core 地址", - "Initialize sandbox deployment": "初始化沙箱部署", "Copied": "已复制", "Select the command above and copy it manually.": "请选择上方命令并手动复制。", - "Choose the next provider": "选择下一个运行后端", - "Where to run sandboxes": "沙箱运行位置", - "Choose where to run": "选择运行位置", "E2B cloud": "E2B 云端", "Own machines": "自有机器", "Core creates E2B sandboxes directly. No node enrollment is needed.": "Core 直接创建 E2B 沙箱,无需注册节点。", @@ -329,13 +285,8 @@ export const sandbox = { "Console → API Keys": "控制台 → API Keys", "Sandbox API URL": "沙箱 API 地址", "Sandbox data-plane domain": "沙箱数据面域名", - "Leave both endpoint fields blank for official E2B. A compatible service needs its HTTPS API origin and data-plane domain.": "留空使用官方 E2B。兼容服务需同时填写 HTTPS API 地址和数据面域名。", "Enter both a public HTTPS API origin and a domain.": "请同时填写公网 HTTPS API 地址和域名。", - "The key is write-only. It is cleared from this form after submission and never saved in browser storage.": "密钥仅供写入,提交后会从表单清除,不会保存在浏览器存储中。", "Enter a template ID and build UUID separated by a colon.": "请输入模板 ID 和构建 UUID,并用冒号分隔。", - "Immutable Runtime template": "固定版本 Runtime 模板", - "Use the qualified managed Runtime template ID followed by its build UUID. A template alias or a generic E2B template cannot provide Core execution.": "请填写已验证的托管 Runtime 模板 ID 和构建 UUID。模板别名或通用 E2B 模板无法提供 Core 执行能力。", - "Core origin stays unchanged": "Core 地址保持不变", "Deployment provider": "部署运行后端", "Allocated resources": "已分配资源", "Pending environments": "待处理环境", @@ -343,23 +294,14 @@ export const sandbox = { "Configured": "已配置", "Not configured": "未配置", "Saved configuration does not confirm execution readiness. Session and Environment state report actual execution.": "配置已保存不代表执行已就绪。实际执行情况以会话和环境状态为准。", - "Stopped or offline resources, snapshots, uncertain creates and pending environments still block switching. Deleting a Session alone does not prove cleanup; Core must confirm both counts are zero.": "已停止或离线的资源、快照、创建结果未确认的资源和待处理环境均会阻止切换。删除会话并不代表清理完成,需由 Core 确认两项计数均为零。", - "Open Sessions": "打开会话", - "Check cleanup": "检查清理状态", - "Core reports no remaining execution resources. You can choose the next provider.": "Core 确认已无剩余执行资源,可以选择下一个运行后端。", - "Provider changes are blocked until Core confirms complete cleanup.": "Core 确认清理完成前无法更改运行后端。", "Cancel": "取消", - "Resume hosted placement": "恢复托管分配", "Refresh sandbox state to confirm whether the change was saved before submitting again.": "再次提交前,请刷新沙箱状态以确认更改是否已保存。", - "Hosted sandboxes": "托管沙箱", - "Manage hosted execution for this Core deployment.": "管理此 Core 部署的托管执行。", "Status": "状态", "Added": "加入时间", "Back": "返回", "Node not found": "找不到此节点", "This node is not registered. It may have been removed.": "此节点未注册,可能已被移除。", "Capacity": "容量", - "Free memory": "可用内存", "Free disk": "可用磁盘", "Issue": "异常", "Created": "创建时间", @@ -406,7 +348,6 @@ export const sandbox = { "Idle suspension": "空闲挂起", "After {{idle}} · kept {{retention}}": "{{idle}}后 · 保留 {{retention}}", "Current": "当前规格", - "The exact ready build, as template-id:build-uuid. A template alias alone is not enough. Each sandbox gets the build's CPU and memory.": "精确的已就绪构建,格式为 template-id:build-uuid,只填模板别名不行。每个沙箱按这个构建分配 CPU 和内存。", "The key is write-only: Core encrypts it and never shows it again.": "key 只写入:Core 加密保存,之后不再显示。", "This console serves no Runtime manifest. Enter the release under advanced settings.": "这个控制台没有提供 Runtime 清单,请在高级设置里填写。", "Where should sandboxes run?": "沙箱在哪里运行?", diff --git a/apps/web/src/i18n/locales/zh-CN/sessions.ts b/apps/web/src/i18n/locales/zh-CN/sessions.ts index b6e1455da..d89a0e56e 100644 --- a/apps/web/src/i18n/locales/zh-CN/sessions.ts +++ b/apps/web/src/i18n/locales/zh-CN/sessions.ts @@ -15,7 +15,7 @@ export const sessions = { sessionStatus: { all: "全部", in_progress: "运行中", requires_action: "等待调用方", failed: "失败", idle: "空闲", other: "其他" }, environment: { none: "无环境", self_hosted: "自托管", openai_hosted: "托管沙箱", other: "其他" }, harness: coreHarnessNames, - usage: { input: "输入", output: "输出", total: "总计", cached: "缓存", reasoning: "推理" }, + usage: { input: "输入", output: "输出", total: "总计" }, log: { title: "Session 日志", help: "调用方用各项目的 API key 创建的 Session,按最近活跃排序。控制台只读取 Session,并可删除空闲的 Session;打开 Session 可查看对话、追踪和 Turn。", @@ -99,7 +99,6 @@ export const sessions = { noItems: "还没有条目", itemsFailed: "无法加载条目:{{reason}}", turnsFailed: "无法加载 Turn:{{reason}}", - user: "用户", error: "错误", unassociated: "未关联 Turn", steps: "{{n}} 个步骤", @@ -117,7 +116,6 @@ export const sessions = { output: "输出", total: "总 Token", number: "Turn {{number}}", - errorLabel: "Turn 错误", none: "还没有 Turn", }, runtime: { @@ -150,7 +148,6 @@ export const sessions = { status: { never_enrolled: "尚未连接", connected: "已连接", disconnected: "已断开", revoked: "绑定凭证已撤销", unknown: "未知" }, boundKey: "绑定凭证", lastSeen: "最后在线", - notBound: "尚未绑定", noHeartbeat: "尚无心跳记录", stale: "刷新失败。当前显示上次读取的绑定信息,连接状态未知。", refreshing: "正在刷新上次读取的绑定信息,尚未确认当前连接。", @@ -274,7 +271,7 @@ export const sessions = { ...english.trace, source: "来源", agentSnapshot: "Agent 配置快照", itemSnapshot: "持久化条目快照", notApplicable: "不适用", group: "分组", configuredModel: "配置的模型", itemTiming: "条目时间", notProvidedByCore: "Core 未提供", toolReportedDuration: "工具报告耗时", turnScopedUsage: "Turn 范围令牌用量", turnScopedTokens: "Turn 令牌", scopeBoundary: "此视图报告 Core 资源范围,不推断模型跨度、提供商、请求步骤或子 Agent 关系。", contractUnavailable: "当前 Core 合约未提供。", - turnStarted: "Turn 开始", turnCompleted: "Turn 完成", turnWallClock: "Turn 总耗时", itemStarted: "条目开始", itemCompleted: "条目完成", timingBoundary: "Turn 时间戳是服务端资源。工具耗时没有公开的绝对开始时间,因此不会定位到按时间缩放的瀑布图中。", + turnStarted: "Turn 开始", turnCompleted: "Turn 完成", turnWallClock: "Turn 总耗时", knownTurnTime: "已知 Turn 耗时", turns: "Turn", toolCalls: "工具调用", search: "搜索追踪", durableExecutionOrder: "持久化执行顺序", durableOrder: "持久化顺序", equalWidth: "等宽序列 · 不按时间缩放", lane: { input: "输入", model: "模型", tools: "工具" }, label: { system: "系统", user: "用户", assistant: "助手", tool: "工具", item: "条目" }, openItem: "打开 {{label}} 追踪条目:{{title}}", contractNote: "Core 报告 Turn 总耗时,但不报告逐条目时间。行会保持持久化顺序,且不按时间缩放。", loadingHistory: "正在加载完整的持久化 Turn 与条目历史…", @@ -283,31 +280,6 @@ export const sessions = { toolDurationSentence: "工具报告耗时:{{duration}}。", toolDuration: "工具报告耗时:{{duration}}", durationUnknown: "报告的耗时未知。", durationInvalid: "无法解析报告的耗时。", perItemNotProvided: "Core 未提供逐条目时间。", perItemTimingMissing: "Core 不提供逐条目时间。", turnDuration: "Turn {{duration}}", turnTimeUnknown: "Turn 耗时未知", turnTimeNotProvided: "未提供 Turn 耗时", payloadAvailable: "载荷可用", resultAvailable: "结果可用", noPreview: "无可用预览", configuredInstructions: "已配置指令", userMessage: "用户消息", assistantMessage: "助手消息", unsupportedItem: "不支持的条目", agentConfiguration: "Agent 配置", turnNumber: "Turn {{number}}", unassociatedItemsNumber: "未关联条目 {{number}}", unknownCount: "{{count}} 个未知", }, - validation: { - ...english.validation, - absoluteWorkspace: "工作区目录必须是绝对 POSIX 路径,例如 /workspace。", - safeWorkspace: "工作区目录不能包含 NUL、回车、换行或反斜杠字符。", - unsupportedNetworkPolicy: "不支持所选的托管环境网络策略。", - invalidTemplateId: "所选环境模板标识符无效。", - unsupportedEnvironmentType: "不支持所选的环境类型。", - invalidEnvironmentInput: "环境输入无效。", - invalidNoEnvironment: "无环境请求包含不支持的字段。", - invalidSelfHosted: "自托管环境请求不符合 Web 支持的配置。", - invalidManaged: "托管环境请求不符合支持的基础配置。", - firstMessageRequired: "未使用环境时,必须填写首条消息。", - nonblankFirstMessage: "请输入非空的首条消息。", - addUserMessage: "请至少添加一条用户消息。", - supportedTextParts: "用户消息 {{number}} 必须包含受支持的文本片段。", - nonblankTextParts: "用户消息 {{number}} 的文本片段中必须包含非空文本。", - atLeastOneTextPart: "用户消息 {{number}} 至少需要一个文本片段。", - selectSavedAgent: "配置 Session 专用覆盖项前,请先选择已保存的 Agent。", - nonemptyModelOverride: "请输入非空的 Session 模型覆盖值。", - inlineMustNotSendId: "创建内联 Agent Session 时不得发送 agent_id。", - invalidInlineProfile: "内联 Agent 请求超出 Web 支持的配置范围。", - selectLoadedOrInline: "请选择已加载的已保存 Agent,或使用内联 Agent。", - savedAgentNotLoaded: "所选的已保存 Agent 尚未加载。", - invalidOverrideProfile: "Session 专用 Agent 覆盖项超出 Web 支持的配置范围。", - }, actions: { ...english.actions, errors: { diff --git a/apps/web/src/i18n/locales/zh-CN/skills.ts b/apps/web/src/i18n/locales/zh-CN/skills.ts index 5c342bc30..9b1178082 100644 --- a/apps/web/src/i18n/locales/zh-CN/skills.ts +++ b/apps/web/src/i18n/locales/zh-CN/skills.ts @@ -37,22 +37,14 @@ export const skills = { defaultVersion: "默认版本", latestVersion: "最新版本", created: "创建时间", - id: "ID", newerThanDefault: "有未启用的新版本", newerThanDefaultHelp: "已有更新的版本,但尚未设为默认。新建 Session 仍会使用默认版本。", noMatchTitle: "没有匹配的已加载 Skill", - noMatchDescription: "筛选只作用于已加载的 Skill。可以加载更多,或清除筛选。", - loadFailed: "无法加载 Skill", - refreshFailed: "刷新失败,下面是之前加载的 Skill。{{reason}}", moreFailed: "无法加载下一页。{{reason}}", }, empty: { title: "还没有 Skill", }, - unsupported: { - title: "当前 Core 不提供 Skill", - description: "所连接的 Core 对 Skill 列表请求返回了 {{status}}。", - }, detail: { loading: "正在加载 Skill…", facts: "Skill 详情", @@ -81,16 +73,6 @@ export const skills = { downloaded: "已保存 {{filename}}", actionFailed: "请求失败。{{reason}}", }, - setDefault: { - title: "将 v{{version}} 设为默认?", - newSessions: "之后新建的 Session 如果引用这个 Skill 时没有指定版本,会使用 v{{version}}。", - existingSessions: "已有的 Session 不受影响。", - metadata: "这个 Skill 的名称和描述会变成 v{{version}} 的。", - metadataChange: "这个 Skill 的名称和描述会变成 v{{version}} 的:{{name}}。", - confirm: "设为默认", - saving: "保存中…", - done: "v{{version}} 已设为默认", - }, deleteVersion: { title: "删除 v{{version}}?", body: "删除后版本号不会被复用;已有 Session 不受影响。", @@ -113,69 +95,4 @@ export const skills = { deleting: "删除中…", done: "{{name}} 已删除", }, - upload: { - title: "上传 Skill", - versionTitle: "上传 {{name}} 的新版本", - source: "上传方式", - zip: "ZIP 文件", - folder: "文件夹", - zipInput: "选择 ZIP 文件", - folderInput: "选择文件夹", - reading: "正在读取所选内容…", - setDefault: "设为默认版本", - setDefaultHelp: "之后新建的 Session 如果引用这个 Skill 时没有指定版本,会使用这个版本,Skill 的名称和描述也会随之改变。已有的 Session 不受影响。", - submit: "上传", - uploading: "上传中…", - cancelUpload: "取消上传", - created: "{{name}} 已上传", - versionCreated: "v{{version}} 已上传", - preview: { - label: "所选内容", - folder: "文件夹", - files: "文件数", - size: "大小", - archive: "ZIP 大小", - name: "名称", - description: "描述", - missing: "未找到", - }, - requirements: { - title: "格式要求", - folder: "只有一个顶层文件夹,并且里面有 SKILL.md。", - frontmatter: "SKILL.md 的 frontmatter 只支持 name、description、license、compatibility 和字符串类型的 metadata;hooks、权限控制和 subagent 指令都会被拒绝。", - files: "只能是普通文件:不能有软链接、特殊文件和路径穿越。", - limits: "压缩后不超过 5 MiB,解压后不超过 20 MiB;上传文件夹最多 500 个文件,ZIP 最多 1,000 个条目。", - authority: "这些是当前 Core 的限制,不是上游协议的上限。最终以 Core 的校验为准。", - }, - issues: { - noFiles: "所选内容里没有文件。", - tooManyFiles: "共 {{count}} 个文件,超过上限 {{limit}} 个。", - tooLarge: "解压后 {{size}},超过上限 {{limit}}。", - zipTooLarge: "ZIP 大小为 {{size}},上限为 {{limit}}。", - notZip: "请选择扩展名为 .zip 的文件。", - multipleTopLevel: "请把所有内容放进一个顶层文件夹。当前有:{{names}}", - outsideFolder: "这些文件不在文件夹里:{{paths}}", - missingManifest: "缺少 {{folder}}/SKILL.md。", - invalidPath: "不支持的路径:{{paths}}", - duplicatePath: "重复的路径:{{paths}}", - hiddenFiles: "隐藏文件会原样上传:{{paths}}", - more: "{{list}} 等 {{count}} 个", - manifestUnreadable: "无法读取 SKILL.md 用于预览。", - zipUnreadable: "无法读取这个 ZIP 用于预览,Core 仍会校验它。", - frontmatterMissing: "SKILL.md 不是以 --- frontmatter 开头。", - frontmatterInvalid: "SKILL.md 的 frontmatter 有部分内容无法读取。", - nameMissing: "frontmatter 里没有 name。", - descriptionMissing: "frontmatter 里没有 description。", - unsupportedKeys: "Core 会拒绝这些 frontmatter 字段:{{keys}}", - nameFormat: "Core 要求 name 只包含小写字母、数字、- 和 _,最长 64 个字符。", - }, - errors: { - invalid: "Core 拒绝了这个 Skill:{{message}}", - tooLarge: "文件超出大小限制。", - interrupted: "上传没有完成。已选的文件仍然保留;Core 可能已经保存了它,重试前请先查看列表。", - cancelled: "已取消上传。已选的文件仍然保留;Core 可能已经保存了它,重试前请先查看列表。", - other: "上传失败:{{message}}", - seeRequirements: "格式要求", - }, - }, } as const; diff --git a/apps/web/src/i18n/locales/zh-CN/system.ts b/apps/web/src/i18n/locales/zh-CN/system.ts index d59d5e6c6..6e0551132 100644 --- a/apps/web/src/i18n/locales/zh-CN/system.ts +++ b/apps/web/src/i18n/locales/zh-CN/system.ts @@ -12,7 +12,6 @@ export const system: TranslationShape = { apiBaseUrl: "API 基础地址", apiBaseUrlHelp: "应用把它设为 OPENAI_BASE_URL,并把项目 API 密钥设为 OPENAI_API_KEY。", copyApiBaseUrl: "复制 API 基础地址", - localOnly: "只能在 Core 所在的机器上访问", details: "安装详情", id: "安装 ID", sourceCommit: "源码提交", diff --git a/apps/web/src/i18n/locales/zh-CN/templates.ts b/apps/web/src/i18n/locales/zh-CN/templates.ts index fad278f70..3009612b5 100644 --- a/apps/web/src/i18n/locales/zh-CN/templates.ts +++ b/apps/web/src/i18n/locales/zh-CN/templates.ts @@ -3,25 +3,22 @@ type TranslationShape = { [K in keyof T]: T[K] extends string ? string : Tran export const templates: TranslationShape = { boundary: "模板由应用使用项目 API 密钥通过 Agents API 创建和修改;控制台只查看和删除。", refreshFailed: "无法刷新目录。请检查连接后重试。", - savedRefreshFailed: "更改已保存,但目录刷新失败。请先刷新再进行其他更改。", created: "模板已创建,未分配运行时。", updated: "模板已更新。现有 Session 会保留原配置。", deleted: "模板已删除。", - loading: "正在加载环境模板…", unavailableTitle: "环境模板不可用", unavailableDescription: "此 Core 未提供模板资源,Web 不会推断目录。", - loadFailedTitle: "无法加载环境模板", loadFailedDescription: "请检查 Core 连接和访问权限;目录当前不可用。", configureConnection: "配置连接", + loading: "正在加载环境模板…", + loadFailedTitle: "无法加载环境模板", filterLabel: "筛选模板", filterPlaceholder: "按名称或 ID 筛选", count: "显示 {{visible}} / {{total}} 个模板", emptyTitle: "还没有环境模板", noMatch: "没有匹配的模板", clearFilter: "清除筛选", listLabel: "环境模板", columns: { name: "名称", network: "网络", packages: "依赖包", files: "文件", skills: "Skill", plugins: "Plugin", updated: "更新时间", actions: "操作" }, access: { enabled: "已启用", disabled: "已禁用", restricted: "受限" }, accessHelp: { - enabled: "原生工具可以访问任意主机。", - disabled: "原生工具无法访问网络。", restricted: "原生工具只能访问列出的主机名。子域名和重定向目标需要单独列出。", }, - edit: "编辑", editLabel: "编辑 {{name}}", delete: "删除", deleteLabel: "删除 {{name}}", open: "打开 {{name}}", back: "返回", + edit: "编辑", delete: "删除", deleteLabel: "删除 {{name}}", open: "打开 {{name}}", back: "返回", unrecognized: "含无法识别的配置", unrecognizedHelp: "Core 返回了控制台无法识别的配置。可识别的部分照常显示,其余部分不做推测。", unrecognizedSections: "控制台无法识别:{{sections}}", unrecognizedValue: "无法识别", - modal: { delete: "删除模板?", edit: "编辑模板", create: "创建模板" }, deletePrompt: "删除 {{name}}?", deleteWarning: "新 Session 将无法再选择此模板。已创建的 Session 不受影响。此操作无法撤销。", deleting: "删除中…", deleteTemplate: "删除模板", unnamed: "未命名模板", + modal: { delete: "删除模板?" }, deletePrompt: "删除 {{name}}?", deleteWarning: "新 Session 将无法再选择此模板。已创建的 Session 不受影响。此操作无法撤销。", deleting: "删除中…", deleteTemplate: "删除模板", unnamed: "未命名模板", detail: { facts: "模板信息", id: "模板 ID", @@ -74,8 +71,6 @@ export const templates: TranslationShape = { saving: "保存中…", saveChanges: "保存更改", create: "创建模板", }, errors: { - forbidden: "Core 拒绝了此请求。请检查连接和访问权限。", - missing: "此模板已不存在。请刷新目录后重试。", invalid: "Core 拒绝了模板配置:{{reason}}", uncertain: "未能确认写入结果。再次更改前请刷新并检查 Core 目录;请求未被重放。", }, diff --git a/apps/web/src/i18n/locales/zh-CN/vaults.ts b/apps/web/src/i18n/locales/zh-CN/vaults.ts index 6da976153..8c8c9ed1e 100644 --- a/apps/web/src/i18n/locales/zh-CN/vaults.ts +++ b/apps/web/src/i18n/locales/zh-CN/vaults.ts @@ -2,11 +2,9 @@ import type { vaults as english } from "../en/vaults"; type TranslationShape = { [K in keyof T]: T[K] extends string ? string : TranslationShape }; export const vaults: TranslationShape = { securityNote: "令牌只可写入。此页面只接收 Credential 元数据,绝不会接收令牌值。删除 Vault 也会删除其中保存的所有 Credential,但不会撤销 provider 侧令牌。", - actionNotConfirmed: "操作未确认", mutationUncertain: "未能确认写入结果。目录已刷新;再次明确重试前请检查当前 Core 状态。", loading: "正在加载 Vault", loadFailed: "无法加载 Vault", refreshFailed: "无法刷新 Vault", failedDescription: "Web 无法加载完整的 Vault 和 Credential 目录。", staleDescription: "之前的安全元数据快照仍可见,但不能授权新 Session。", failedHint: "请检查 Core 连接后刷新。在完整目录加载前,需要 Credential 的 Session 会保持阻止状态。", - credential: "Credential", deleteVaultLabel: "删除 {{name}}", created: "创建时间", credentialsIn: "{{name}} 中的 Credential", updatedHidden: "更新于 {{date}} · 令牌已隐藏", oauthHelp: "OAuth · 请在你的应用中管理授权和令牌替换。", replaceTokenLabel: "替换 {{name}} 的令牌", replaceToken: "替换令牌", deleteCredentialLabel: "删除 {{name}}", noCredentials: "此 Vault 中没有 Credential。", noVaults: "还没有 Vault", createVault: "创建 Vault", createVaultTitle: "创建 Vault", deleteVaultTitle: "删除 Vault?", deleteCredentialTitle: "删除 Credential?", deleting: "删除中…", delete: "删除", deleteVaultPrompt: "删除 {{name}} 及其中保存的全部 Credential?现有 Session 会保留冻结的 ID,但后续密钥读取会失败。Provider 令牌和正在运行的工作不会被撤销。", deleteCredentialPrompt: "删除 {{name}}?现有 Session 会保留其冻结标识,但后续密钥读取会失败。此操作不会撤销 MCP provider 上的令牌。", unnamed: "未命名 Vault", - list: { label: "Vault", filterLabel: "筛选 Vault", filterPlaceholder: "按名称或 ID 筛选", name: "名称", credentials: "Credential", created: "创建时间", actions: "操作", open: "打开 {{name}}", noMatch: "没有匹配的 Vault" }, + loading: "正在加载 Vault", loadFailed: "无法加载 Vault", refreshFailed: "无法刷新 Vault", + credential: "Credential", deleteVaultLabel: "删除 {{name}}", created: "创建时间", credentialsIn: "{{name}} 中的 Credential", oauthHelp: "OAuth · 请在你的应用中管理授权和令牌替换。", deleteCredentialLabel: "删除 {{name}}", noCredentials: "此 Vault 中没有 Credential。", noVaults: "还没有 Vault", deleteVaultTitle: "删除 Vault?", deleteCredentialTitle: "删除 Credential?", deleting: "删除中…", delete: "删除", deleteVaultPrompt: "删除 {{name}} 及其中保存的全部 Credential?现有 Session 会保留冻结的 ID,但后续密钥读取会失败。Provider 令牌和正在运行的工作不会被撤销。", deleteCredentialPrompt: "删除 {{name}}?现有 Session 会保留其冻结标识,但后续密钥读取会失败。此操作不会撤销 MCP provider 上的令牌。", unnamed: "未命名 Vault", + list: { label: "Vault", filterLabel: "筛选 Vault", filterPlaceholder: "按名称或 ID 筛选", name: "名称", created: "创建时间", actions: "操作", open: "打开 {{name}}", noMatch: "没有匹配的 Vault" }, detail: { back: "返回", facts: "Vault 详情", id: "ID", created: "创建时间", metadata: "元数据", credentials: "Credential", credentialsHelp: "静态 bearer 令牌只可写入:Core 不会返回令牌,所以这里只显示元数据。替换令牌不会在 provider 侧撤销旧令牌。", name: "名称", url: "MCP 服务 URL", auth: "认证方式", updated: "更新时间", addCredential: "添加 Credential", deleteVault: "删除 Vault", staticBearer: "静态 bearer", oauth: "OAuth", tokenHidden: "令牌已隐藏" }, - createForm: { name: "名称", namePlaceholder: "运行时 Credential", nameHelp: "必填。去除首尾空格后的名称最多 256 个 UTF-8 字节。", metadata: "元数据", optional: "可选", metadataHelp: "输入值为字符串的 JSON 对象。留空会转为 {{emptyObject}};编码后的元数据最大为 64 KiB。", metadataWarning: "Vault 元数据是公开的。切勿在此填写密钥、令牌、密码、凭据或私有连接信息。", creating: "创建中…", create: "创建 Vault" }, - credentialDialog: { replaceTitle: "替换令牌 · {{name}}", addTitle: "添加静态 bearer Credential", saving: "保存中…", create: "创建 Credential", notConfirmed: "Credential 未确认", name: "名称", namePlaceholder: "内部 MCP", exactUrl: "精确 MCP 服务 URL", urlHelp: "此 URL 必须与 Agent MCP 定义完全一致。创建此资源不会发起网络请求。", replaceWarning: "旧令牌不会被读取或显示。正在运行的工作可能已经持有它;替换操作不会撤销 provider 侧令牌。", newToken: "新 bearer 令牌", token: "Bearer 令牌", tokenHelp: "只可写入。令牌只发送一次,随后立即清除,且绝不会保存到浏览器状态、元数据、预览或日志中。" }, - errors: { auth: "Core 认证失败,Credential 未确认。", missing: "Vault 或 Credential 已不存在。请刷新后重试。", tooLarge: "Credential 请求超过 Core 接受的大小。", invalidFields: "Core 拒绝了 Credential 字段。请检查名称、精确 HTTPS URL 和令牌格式。", credentialUncertain: "未能确认 Credential 写入结果。目录已刷新;再次明确重试前请先检查。", bearer: "请输入非空的 RFC 6750 bearer 令牌。空白或其他仅能保存的不透明值无法在当前运行时执行。", credentialName: "Credential 名称必须为 1 至 256 个 UTF-8 字节。", exactUrl: "请输入不含凭据、查询参数、片段、空白或反斜杠的精确 HTTPS MCP URL。", createUncertain: "未能确认 Vault 创建结果。草稿保持不变;再次明确重试前请检查当前 Core 状态。", vaultName: "名称必须为 1 至 256 个 UTF-8 字节。", metadataUnknown: "无法验证元数据。", metadataJson: "元数据必须是有效 JSON。", metadataShape: "元数据必须是值为字符串的 JSON 对象。", metadataStrings: "元数据值必须全部为字符串;不支持嵌套值、数组、数字、布尔值和 null。", metadataLarge: "元数据经 UTF-8 JSON 编码后最大为 64 KiB。", mismatchedMetadata: "OpenAgentCore 返回的 Vault 元数据不匹配。", uniqueAttachments: "附加的 Vault 不能重复。", catalogIncomplete: "尚未从此 Core 完整加载 Credential 元数据。", vaultMissing: "所选 Vault 已不在当前目录中。", credentialMismatch: "MCP 服务 {{server}} 引用了不可用或 URL 不匹配的 Credential。", credentialVaultMissing: "MCP 服务 {{server}} 引用的 Credential 所属 Vault 不可用。", multipleCredentials: "匿名 MCP 服务 {{server}} 在所选 Vault 中匹配到多个 Credential。请选择唯一匹配的 Vault,或明确配置一个 Credential。", matchedVaultMissing: "MCP 服务 {{server}} 匹配到的 Credential 所属 Vault 不可用。" }, + errors: { tooLarge: "Credential 请求超过 Core 接受的大小。", uniqueAttachments: "附加的 Vault 不能重复。", catalogIncomplete: "尚未从此 Core 完整加载 Credential 元数据。", vaultMissing: "所选 Vault 已不在当前目录中。", credentialMismatch: "MCP 服务 {{server}} 引用了不可用或 URL 不匹配的 Credential。", credentialVaultMissing: "MCP 服务 {{server}} 引用的 Credential 所属 Vault 不可用。", multipleCredentials: "匿名 MCP 服务 {{server}} 在所选 Vault 中匹配到多个 Credential。请选择唯一匹配的 Vault,或明确配置一个 Credential。", matchedVaultMissing: "MCP 服务 {{server}} 匹配到的 Credential 所属 Vault 不可用。" }, }; diff --git a/apps/web/src/i18n/resources.ts b/apps/web/src/i18n/resources.ts index cb6b2e141..07f5a64cb 100644 --- a/apps/web/src/i18n/resources.ts +++ b/apps/web/src/i18n/resources.ts @@ -13,7 +13,6 @@ import { agents as enAgents } from "./locales/en/agents"; import { templates as enTemplates } from "./locales/en/templates"; import { vaults as enVaults } from "./locales/en/vaults"; import { files as enFiles } from "./locales/en/files"; -import { dashboard as enDashboard } from "./locales/en/dashboard"; import { sessions as enSessions } from "./locales/en/sessions"; import { overview as enOverview } from "./locales/en/overview"; import { metrics as enMetrics } from "./locales/en/metrics"; @@ -28,7 +27,6 @@ import { agents as zhCNAgents } from "./locales/zh-CN/agents"; import { templates as zhCNTemplates } from "./locales/zh-CN/templates"; import { vaults as zhCNVaults } from "./locales/zh-CN/vaults"; import { files as zhCNFiles } from "./locales/zh-CN/files"; -import { dashboard as zhCNDashboard } from "./locales/zh-CN/dashboard"; import { sessions as zhCNSessions } from "./locales/zh-CN/sessions"; import { overview as zhCNOverview } from "./locales/zh-CN/overview"; import { metrics as zhCNMetrics } from "./locales/zh-CN/metrics"; @@ -60,7 +58,6 @@ export const resources = { templates: enTemplates, vaults: enVaults, files: enFiles, - dashboard: enDashboard, sessions: enSessions, diagnostics: enDiagnostics, overview: enOverview, @@ -83,7 +80,6 @@ export const resources = { templates: zhCNTemplates, vaults: zhCNVaults, files: zhCNFiles, - dashboard: zhCNDashboard, sessions: zhCNSessions, diagnostics: zhDiagnostics, overview: zhCNOverview, diff --git a/apps/web/src/lib/console-routes.test.ts b/apps/web/src/lib/console-routes.test.ts index 1fc5d04ed..db6e5bc49 100644 --- a/apps/web/src/lib/console-routes.test.ts +++ b/apps/web/src/lib/console-routes.test.ts @@ -13,15 +13,10 @@ describe("console routes", () => { ]); }); - it("routes hashes, keeps old bookmarks and falls back to the overview", () => { + it("routes hashes and falls back to the overview", () => { expect(consoleViewFromHash("")).toBe("overview"); expect(consoleViewFromHash("#vaults")).toBe("vaults"); expect(consoleViewFromHash("#session?project=proj_1&id=s1")).toBe("session"); - expect(consoleViewFromHash("#builder")).toBe("agents"); - expect(consoleViewFromHash("#playground")).toBe("sessions"); - expect(consoleViewFromHash("#workbench")).toBe("overview"); - expect(consoleViewFromHash("#sandbox")).toBe("nodes"); - expect(consoleViewFromHash("#api-keys")).toBe("projects"); expect(consoleViewFromHash("#unknown")).toBe("overview"); expect(consoleHashForView("overview")).toBe(""); expect(consoleHashForView("settings")).toBe("#settings"); diff --git a/apps/web/src/lib/console-routes.ts b/apps/web/src/lib/console-routes.ts index 2c9cbe1ab..4ea7fb9f4 100644 --- a/apps/web/src/lib/console-routes.ts +++ b/apps/web/src/lib/console-routes.ts @@ -47,19 +47,9 @@ const routedViews = new Set([ ...Object.keys(consoleSecondaryViews), ]); -/** Earlier console releases used these hashes; keep bookmarks working. */ -const legacyHashes: Readonly> = { - dashboard: "overview", - sandbox: "nodes", - builder: "agents", - playground: "sessions", - workbench: "overview", - "api-keys": "projects", -}; - export function consoleViewFromHash(hash: string): ConsoleView { const candidate = hash.startsWith("#") ? hash.slice(1).split("?")[0]! : hash; - return legacyHashes[candidate] ?? (routedViews.has(candidate) ? candidate as ConsoleView : "overview"); + return routedViews.has(candidate) ? candidate as ConsoleView : "overview"; } export function consoleHashForView(view: ConsoleView): string { From 7692bbd69d907513ab35780c52cfbc2c2a02acf2 Mon Sep 17 00:00:00 2001 From: SaladDay <1203511142@qq.com> Date: Wed, 14 Oct 2026 08:04:11 +0000 Subject: [PATCH 2/8] Align console terminology and empty states --- apps/web/e2e/nodes.spec.ts | 4 +- apps/web/e2e/provider-observations.spec.ts | 2 +- apps/web/e2e/resources.spec.ts | 2 +- apps/web/src/features/sandbox/NodeDetail.tsx | 2 +- .../features/sandbox/SandboxManagerView.tsx | 2 +- .../features/sandbox/SandboxSetupWizard.tsx | 2 +- apps/web/src/i18n/i18n.test.tsx | 4 +- apps/web/src/i18n/locales/en/common.ts | 2 +- apps/web/src/i18n/locales/en/diagnostics.ts | 2 +- apps/web/src/i18n/locales/en/files.ts | 4 +- apps/web/src/i18n/locales/en/keys.ts | 4 +- apps/web/src/i18n/locales/en/metrics.ts | 4 +- apps/web/src/i18n/locales/en/pages.ts | 2 +- apps/web/src/i18n/locales/en/sessions.ts | 10 +- apps/web/src/i18n/locales/en/system.ts | 2 +- apps/web/src/i18n/locales/en/templates.ts | 30 +++--- apps/web/src/i18n/locales/en/vaults.ts | 2 +- apps/web/src/i18n/locales/zh-CN/agents.ts | 2 +- .../web/src/i18n/locales/zh-CN/core-errors.ts | 6 +- .../web/src/i18n/locales/zh-CN/diagnostics.ts | 4 +- apps/web/src/i18n/locales/zh-CN/keys.ts | 2 +- apps/web/src/i18n/locales/zh-CN/metrics.ts | 44 ++++----- apps/web/src/i18n/locales/zh-CN/onboarding.ts | 2 +- apps/web/src/i18n/locales/zh-CN/overview.ts | 8 +- apps/web/src/i18n/locales/zh-CN/sandbox.ts | 42 ++++---- apps/web/src/i18n/locales/zh-CN/sessions.ts | 96 +++++++++---------- apps/web/src/i18n/locales/zh-CN/system.ts | 4 +- apps/web/src/i18n/locales/zh-CN/templates.ts | 2 +- apps/web/src/i18n/locales/zh-CN/vaults.ts | 6 +- 29 files changed, 149 insertions(+), 149 deletions(-) diff --git a/apps/web/e2e/nodes.spec.ts b/apps/web/e2e/nodes.spec.ts index 836049f0d..9c2a4a08f 100644 --- a/apps/web/e2e/nodes.spec.ts +++ b/apps/web/e2e/nodes.spec.ts @@ -247,7 +247,7 @@ test("saves E2B without opening Add node, as it has no machines", async ({ page, await expect(page.getByLabel("E2B provider")).toHaveValue("sandbase"); await expect(page.getByLabel("Sandbox API URL")).toHaveValue("https://sandbox.sandbase.ai"); await expect(page.getByLabel("Sandbox data-plane domain")).toHaveValue("sandbox.sandbase.ai"); - const keyConsole = page.getByRole("link", { name: "Console → API Keys" }); + const keyConsole = page.getByRole("link", { name: "Console → API keys" }); await expect(keyConsole.locator("..")).toHaveClass(/field-label-row/); await expect(keyConsole).toHaveCSS("font-size", "11px"); await expect(keyConsole).toHaveAttribute("href", "https://www.sandbase.ai/console/keys"); @@ -272,7 +272,7 @@ test("uses the official E2B preset and clears a selected build when the key chan await page.getByLabel("E2B provider").selectOption("official"); await expect(page.getByLabel("Sandbox API URL")).toHaveValue("https://api.e2b.app"); await expect(page.getByLabel("Sandbox data-plane domain")).toHaveValue("e2b.app"); - const keyConsole = page.getByRole("link", { name: "Console → API Keys" }); + const keyConsole = page.getByRole("link", { name: "Console → API keys" }); await expect(keyConsole).toHaveAttribute("href", "https://e2b.dev/dashboard?tab=api-keys"); await page.getByLabel("Sandbox API URL").fill("https://custom.e2b.app"); await expect(keyConsole).toHaveCount(0); diff --git a/apps/web/e2e/provider-observations.spec.ts b/apps/web/e2e/provider-observations.spec.ts index b6700897c..03bf103c1 100644 --- a/apps/web/e2e/provider-observations.spec.ts +++ b/apps/web/e2e/provider-observations.spec.ts @@ -18,7 +18,7 @@ test("default provider observations are optional details and recover only on Cor await expect(card).not.toContainText("Last successful use"); await card.getByRole("button", { name: "Usage details", exact: true }).click(); const details = page.getByRole("dialog", { name: "Codex usage details", exact: true }); - await expect(details).toContainText("Not recorded"); + await expect(details).toContainText("Not recorded yet"); await details.getByRole("button", { name: "Close dialog", exact: true }).click(); observation = { last_used_at: null, last_error_code: "authentication_error", last_error_at: "2026-09-28T08:01:00Z" }; await page.getByRole("button", { name: "Refresh system configuration", exact: true }).click(); diff --git a/apps/web/e2e/resources.spec.ts b/apps/web/e2e/resources.spec.ts index d66e89ab7..8ba0c99a1 100644 --- a/apps/web/e2e/resources.spec.ts +++ b/apps/web/e2e/resources.spec.ts @@ -45,7 +45,7 @@ test("reads an Agent saved with a model provider and no harness, without its key test("explains on a fresh install that applications create resources through the Agents API", async ({ page, request }) => { await openConsole(page, request, "agents", { fresh: true }); - for (const [view, title, section] of [["agents", "No Agents yet", "agents"], ["templates", "No Environment Templates yet", "environment-templates"], ["skills", "No Skills yet", "skills"], ["files", "No files yet", "source-files"], ["vaults", "No Vaults yet", "vaults"]]) { + for (const [view, title, section] of [["agents", "No Agents yet", "agents"], ["templates", "No Environment templates yet", "environment-templates"], ["skills", "No Skills yet", "skills"], ["files", "No files yet", "source-files"], ["vaults", "No Vaults yet", "vaults"]]) { await page.goto(`/#${view}`); await expect(page.getByText(title)).toBeVisible(); await expect(page.getByText(/through the Agents API\.$/)).toBeVisible(); diff --git a/apps/web/src/features/sandbox/NodeDetail.tsx b/apps/web/src/features/sandbox/NodeDetail.tsx index 3b53da0f3..ca3429095 100644 --- a/apps/web/src/features/sandbox/NodeDetail.tsx +++ b/apps/web/src/features/sandbox/NodeDetail.tsx @@ -126,7 +126,7 @@ export function NodeDetail({ node, allocations, coreUrl, targetGeneration, stale - ) : } + ) : } ); diff --git a/apps/web/src/features/sandbox/SandboxManagerView.tsx b/apps/web/src/features/sandbox/SandboxManagerView.tsx index bcf272326..c00069381 100644 --- a/apps/web/src/features/sandbox/SandboxManagerView.tsx +++ b/apps/web/src/features/sandbox/SandboxManagerView.tsx @@ -232,7 +232,7 @@ function SandboxManager({ consoleConfig }: { consoleConfig: SandboxConsoleConfig {hostedNodes && nodes.some((node) => node.active > node.max_active || node.retained > node.max_retained) ?

{t("Current usage exceeds a saved limit. Existing sandboxes are preserved; new placements wait for capacity.")}

: null} {hostedNodes ? nodes.length ? navigate("nodes", { id: node.id })} onEdit={(node) => setEditId(node.id)} onRemove={askRemove} /> - : nodesConfirmed ? : null + : nodesConfirmed ? : null : null} : null} diff --git a/apps/web/src/features/sandbox/SandboxSetupWizard.tsx b/apps/web/src/features/sandbox/SandboxSetupWizard.tsx index b61508872..4fdf6d6df 100644 --- a/apps/web/src/features/sandbox/SandboxSetupWizard.tsx +++ b/apps/web/src/features/sandbox/SandboxSetupWizard.tsx @@ -304,7 +304,7 @@ export function SandboxSetupWizard({ coreUrl, expectedGeneration, current, disab - {t("Console → API Keys")}