feat(macos): visible-markdown copy, full-message reader, and independent reasoning/tool toggles (#110276)

* feat(clients): copy visible markdown, full-message reader for truncated messages, and independent reasoning/tool toggles

* chore(i18n): translate new reader and trace strings and regenerate catalogs

* test(ios): adopt reader display-options API in render smoke tests
This commit is contained in:
Peter Steinberger
2026-07-18 04:05:50 +01:00
committed by GitHub
parent ff9cb0f679
commit 9dec7acc91
36 changed files with 3171 additions and 717 deletions
+162 -90
View File
@@ -35891,7 +35891,7 @@
},
{
"kind": "ui-localized-call",
"line": 682,
"line": 746,
"path": "apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift",
"source": "Talk mode off",
"surface": "apple",
@@ -35899,7 +35899,7 @@
},
{
"kind": "ui-localized-call",
"line": 683,
"line": 747,
"path": "apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift",
"source": "Talk mode paused",
"surface": "apple",
@@ -35907,7 +35907,7 @@
},
{
"kind": "ui-localized-call",
"line": 685,
"line": 749,
"path": "apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift",
"source": "Talk mode ready",
"surface": "apple",
@@ -35915,7 +35915,7 @@
},
{
"kind": "ui-localized-call",
"line": 686,
"line": 750,
"path": "apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift",
"source": "Listening",
"surface": "apple",
@@ -35923,7 +35923,7 @@
},
{
"kind": "ui-localized-call",
"line": 687,
"line": 751,
"path": "apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift",
"source": "Thinking",
"surface": "apple",
@@ -35931,7 +35931,7 @@
},
{
"kind": "ui-localized-call",
"line": 688,
"line": 752,
"path": "apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift",
"source": "Speaking",
"surface": "apple",
@@ -35939,7 +35939,7 @@
},
{
"kind": "ui-localized-call",
"line": 692,
"line": 756,
"path": "apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift",
"source": "What would you like to work on?",
"surface": "apple",
@@ -35947,7 +35947,7 @@
},
{
"kind": "ui-localized-call",
"line": 696,
"line": 760,
"path": "apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift",
"source": "Check OpenClaw status",
"surface": "apple",
@@ -35955,7 +35955,7 @@
},
{
"kind": "ui-localized-call",
"line": 697,
"line": 761,
"path": "apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift",
"source": "Summarize the current OpenClaw status and tell me what needs attention.",
"surface": "apple",
@@ -35963,7 +35963,7 @@
},
{
"kind": "ui-localized-call",
"line": 700,
"line": 764,
"path": "apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift",
"source": "What can you do?",
"surface": "apple",
@@ -35971,7 +35971,7 @@
},
{
"kind": "ui-localized-call",
"line": 701,
"line": 765,
"path": "apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift",
"source": "Show me what you can help with on this Mac right now.",
"surface": "apple",
@@ -35979,7 +35979,7 @@
},
{
"kind": "ui-localized-call",
"line": 704,
"line": 768,
"path": "apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift",
"source": "Catch me up",
"surface": "apple",
@@ -35987,7 +35987,7 @@
},
{
"kind": "ui-localized-call",
"line": 705,
"line": 769,
"path": "apps/macos/Sources/OpenClaw/WebChatSwiftUI.swift",
"source": "Summarize what happened in my sessions since yesterday.",
"surface": "apple",
@@ -36385,6 +36385,62 @@
"surface": "apple",
"id": "native.apple.9243b96b3d4d590f"
},
{
"kind": "ui-call",
"line": 34,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatFullMessageReader.swift",
"source": "Loading full message…",
"surface": "apple",
"id": "native.apple.ccfd6ae994d82449"
},
{
"kind": "ui-localized-call",
"line": 52,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatFullMessageReader.swift",
"source": "Full message unavailable",
"surface": "apple",
"id": "native.apple.669ad52de4a26b87"
},
{
"kind": "ui-modifier",
"line": 58,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatFullMessageReader.swift",
"source": "Full Message",
"surface": "apple",
"id": "native.apple.6f79794ee74caf99"
},
{
"kind": "ui-call",
"line": 61,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatFullMessageReader.swift",
"source": "Close",
"surface": "apple",
"id": "native.apple.d648251591db5dec"
},
{
"kind": "ui-localized-call",
"line": 77,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatFullMessageReader.swift",
"source": "The full message is no longer available.",
"surface": "apple",
"id": "native.apple.ba3963204bda5e84"
},
{
"kind": "ui-localized-call",
"line": 82,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatFullMessageReader.swift",
"source": "The full message has no readable text.",
"surface": "apple",
"id": "native.apple.8bb98bd86ae85c1c"
},
{
"kind": "ui-localized-call",
"line": 89,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatFullMessageReader.swift",
"source": "The full message could not be loaded.",
"surface": "apple",
"id": "native.apple.2f43669d87c0e26d"
},
{
"kind": "ui-call",
"line": 328,
@@ -36971,7 +37027,7 @@
},
{
"kind": "ui-call",
"line": 457,
"line": 487,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Retry Send",
"surface": "apple",
@@ -36979,7 +37035,7 @@
},
{
"kind": "ui-call",
"line": 471,
"line": 501,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Delete",
"surface": "apple",
@@ -36987,7 +37043,7 @@
},
{
"kind": "ui-call",
"line": 503,
"line": 535,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Stop Listening",
"surface": "apple",
@@ -36995,7 +37051,7 @@
},
{
"kind": "ui-call",
"line": 506,
"line": 538,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Listen",
"surface": "apple",
@@ -37003,39 +37059,7 @@
},
{
"kind": "ui-call",
"line": 550,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Copy Message",
"surface": "apple",
"id": "native.apple.fe9f30f12f1dcfaf"
},
{
"kind": "ui-localized-call",
"line": 571,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Reply",
"surface": "apple",
"id": "native.apple.b37ec7bd7dc1579a"
},
{
"kind": "ui-localized-call",
"line": 581,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "You",
"surface": "apple",
"id": "native.apple.8d80a6bb3d6e99b0"
},
{
"kind": "ui-localized-call",
"line": 583,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Assistant",
"surface": "apple",
"id": "native.apple.3b44a67aa284886f"
},
{
"kind": "ui-call",
"line": 636,
"line": 616,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Jump to latest",
"surface": "apple",
@@ -37043,7 +37067,7 @@
},
{
"kind": "ui-modifier",
"line": 647,
"line": 627,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Jump to latest reply",
"surface": "apple",
@@ -37051,7 +37075,7 @@
},
{
"kind": "ui-named-argument",
"line": 667,
"line": 647,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Refresh",
"surface": "apple",
@@ -37059,7 +37083,47 @@
},
{
"kind": "ui-call",
"line": 1093,
"line": 1033,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Copy Message",
"surface": "apple",
"id": "native.apple.fe9f30f12f1dcfaf"
},
{
"kind": "ui-call",
"line": 1056,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Open Full Message",
"surface": "apple",
"id": "native.apple.90bc8a8045e7017e"
},
{
"kind": "ui-localized-call",
"line": 1077,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Reply",
"surface": "apple",
"id": "native.apple.b37ec7bd7dc1579a"
},
{
"kind": "ui-localized-call",
"line": 1087,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "You",
"surface": "apple",
"id": "native.apple.8d80a6bb3d6e99b0"
},
{
"kind": "ui-localized-call",
"line": 1089,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Assistant",
"surface": "apple",
"id": "native.apple.3b44a67aa284886f"
},
{
"kind": "ui-call",
"line": 1155,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Loading chat",
"surface": "apple",
@@ -37067,7 +37131,7 @@
},
{
"kind": "ui-modifier",
"line": 1173,
"line": 1235,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatView.swift",
"source": "Dismiss",
"surface": "apple",
@@ -37171,7 +37235,7 @@
},
{
"kind": "ui-modifier",
"line": 73,
"line": 77,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Clear this session's history?",
"surface": "apple",
@@ -37179,7 +37243,7 @@
},
{
"kind": "ui-call",
"line": 79,
"line": 83,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Clear History",
"surface": "apple",
@@ -37187,7 +37251,7 @@
},
{
"kind": "ui-localized-call-multiline",
"line": 84,
"line": 88,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "This resets the conversation for %@. The session key stays the same.",
"surface": "apple",
@@ -37195,7 +37259,7 @@
},
{
"kind": "ui-localized-call",
"line": 90,
"line": 94,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Rename Session",
"surface": "apple",
@@ -37203,7 +37267,7 @@
},
{
"kind": "ui-localized-call",
"line": 91,
"line": 95,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Session name",
"surface": "apple",
@@ -37211,7 +37275,7 @@
},
{
"kind": "ui-localized-call",
"line": 92,
"line": 96,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Rename",
"surface": "apple",
@@ -37219,7 +37283,7 @@
},
{
"kind": "ui-localized-call",
"line": 97,
"line": 101,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Cancel",
"surface": "apple",
@@ -37227,7 +37291,7 @@
},
{
"kind": "ui-call",
"line": 138,
"line": 142,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Export Transcript",
"surface": "apple",
@@ -37235,7 +37299,7 @@
},
{
"kind": "ui-call",
"line": 147,
"line": 151,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Sessions",
"surface": "apple",
@@ -37243,7 +37307,7 @@
},
{
"kind": "ui-call",
"line": 231,
"line": 235,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Thinking",
"surface": "apple",
@@ -37251,7 +37315,7 @@
},
{
"kind": "ui-modifier",
"line": 235,
"line": 239,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Thinking level",
"surface": "apple",
@@ -37259,7 +37323,7 @@
},
{
"kind": "ui-call",
"line": 251,
"line": 255,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Pinned",
"surface": "apple",
@@ -37267,7 +37331,7 @@
},
{
"kind": "ui-call",
"line": 254,
"line": 258,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Recent",
"surface": "apple",
@@ -37275,7 +37339,7 @@
},
{
"kind": "ui-call",
"line": 257,
"line": 261,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Models",
"surface": "apple",
@@ -37283,7 +37347,7 @@
},
{
"kind": "ui-call",
"line": 261,
"line": 265,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Model",
"surface": "apple",
@@ -37291,7 +37355,7 @@
},
{
"kind": "ui-call",
"line": 281,
"line": 285,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "New Session",
"surface": "apple",
@@ -37299,7 +37363,7 @@
},
{
"kind": "ui-call",
"line": 289,
"line": 293,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Refresh",
"surface": "apple",
@@ -37307,7 +37371,7 @@
},
{
"kind": "ui-call",
"line": 296,
"line": 300,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Sessions…",
"surface": "apple",
@@ -37315,7 +37379,7 @@
},
{
"kind": "ui-localized-call",
"line": 308,
"line": 312,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Rename Session…",
"surface": "apple",
@@ -37323,7 +37387,7 @@
},
{
"kind": "ui-localized-call",
"line": 316,
"line": 320,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Fork Session",
"surface": "apple",
@@ -37331,7 +37395,7 @@
},
{
"kind": "ui-localized-call",
"line": 327,
"line": 331,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Unpin",
"surface": "apple",
@@ -37339,7 +37403,7 @@
},
{
"kind": "ui-localized-call",
"line": 328,
"line": 332,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Pin",
"surface": "apple",
@@ -37347,7 +37411,7 @@
},
{
"kind": "ui-localized-call",
"line": 339,
"line": 343,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Mark Read",
"surface": "apple",
@@ -37355,7 +37419,7 @@
},
{
"kind": "ui-localized-call",
"line": 340,
"line": 344,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Mark Unread",
"surface": "apple",
@@ -37363,7 +37427,7 @@
},
{
"kind": "ui-localized-call",
"line": 356,
"line": 360,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Restore",
"surface": "apple",
@@ -37371,7 +37435,7 @@
},
{
"kind": "ui-localized-call",
"line": 357,
"line": 361,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Archive",
"surface": "apple",
@@ -37379,7 +37443,7 @@
},
{
"kind": "ui-call",
"line": 369,
"line": 373,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Copy Session Key",
"surface": "apple",
@@ -37387,7 +37451,7 @@
},
{
"kind": "ui-call",
"line": 375,
"line": 379,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Export Transcript…",
"surface": "apple",
@@ -37395,15 +37459,23 @@
},
{
"kind": "ui-call",
"line": 387,
"line": 391,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Show reasoning & tool activity",
"source": "Show Reasoning",
"surface": "apple",
"id": "native.apple.3294ababd29c4457"
"id": "native.apple.ebb130189022c7ec"
},
{
"kind": "ui-call",
"line": 404,
"line": 403,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Show Tool Activity",
"surface": "apple",
"id": "native.apple.d0dba9aad550fa6e"
},
{
"kind": "ui-call",
"line": 420,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Clear History…",
"surface": "apple",
@@ -37411,7 +37483,7 @@
},
{
"kind": "ui-call",
"line": 407,
"line": 423,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Session",
"surface": "apple",
@@ -37419,7 +37491,7 @@
},
{
"kind": "ui-modifier",
"line": 410,
"line": 426,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Session actions",
"surface": "apple",
@@ -37427,7 +37499,7 @@
},
{
"kind": "ui-localized-call",
"line": 444,
"line": 460,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Session cost %@",
"surface": "apple",
@@ -37435,7 +37507,7 @@
},
{
"kind": "ui-call",
"line": 450,
"line": 466,
"path": "apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatWindowShell.swift",
"source": "Compact Session",
"surface": "apple",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "تم استخدام %@ من الرموز"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "جارٍ تحميل الرسالة كاملة…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "الرسالة الكاملة غير متاحة"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "الرسالة الكاملة"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "إغلاق"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "لم تعد الرسالة الكاملة متاحة."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "لا تحتوي الرسالة الكاملة على نص قابل للقراءة."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "تعذّر تحميل الرسالة الكاملة."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "استمع"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "الانتقال إلى الأحدث"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "الانتقال إلى أحدث رد"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "تحديث"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "نسخ الرسالة"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "فتح الرسالة الكاملة"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "المساعد"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "الانتقال إلى الأحدث"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "الانتقال إلى أحدث رد"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "تحديث"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "تصدير النص…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "إظهار الاستدلال ونشاط الأدوات"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "إظهار الاستدلال"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "إظهار نشاط الأداة"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "%@ Token verwendet"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "Vollständige Nachricht wird geladen…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "Vollständige Nachricht nicht verfügbar"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "Vollständige Nachricht"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "Schließen"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "Die vollständige Nachricht ist nicht mehr verfügbar."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "Die vollständige Nachricht enthält keinen lesbaren Text."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "Die vollständige Nachricht konnte nicht geladen werden."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "Zuhören"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Zum neuesten springen"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Zur neuesten Antwort springen"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Aktualisieren"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "Nachricht kopieren"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "Vollständige Nachricht öffnen"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "Assistent"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Zum neuesten springen"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Zur neuesten Antwort springen"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Aktualisieren"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "Transkript exportieren…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "Gedankengang und Werkzeugaktivität anzeigen"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "Gedankengang anzeigen"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "Tool-Aktivität anzeigen"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "%@ tokens utilizados"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "Cargando el mensaje completo…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "Mensaje completo no disponible"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "Mensaje completo"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "Cerrar"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "El mensaje completo ya no está disponible."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "El mensaje completo no contiene texto legible."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "No se pudo cargar el mensaje completo."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "Escuchar"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Ir a lo más reciente"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Ir a la respuesta más reciente"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Actualizar"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "Copiar mensaje"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "Abrir mensaje completo"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "Asistente"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Ir a lo más reciente"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Ir a la respuesta más reciente"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Actualizar"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "Exportar transcripción…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "Mostrar el razonamiento y la actividad de las herramientas"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "Mostrar razonamiento"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "Mostrar actividad de las herramientas"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "%@ توکن استفاده شده است"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "در حال بارگذاری پیام کامل…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "پیام کامل در دسترس نیست"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "پیام کامل"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "بستن"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "پیام کامل دیگر در دسترس نیست."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "پیام کامل متن خوانایی ندارد."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "پیام کامل بارگذاری نشد."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "گوش دادن"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "پرش به آخرین مورد"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "پرش به آخرین پاسخ"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "تازه‌سازی"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "کپی پیام"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "باز کردن پیام کامل"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "دستیار"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "پرش به آخرین مورد"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "پرش به آخرین پاسخ"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "تازه‌سازی"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "خروجی گرفتن رونوشت…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "نمایش استدلال و فعالیت ابزارها"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "نمایش استدلال"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "نمایش فعالیت ابزار"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "%@ jetons utilisés"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "Chargement du message complet…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "Message complet indisponible"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "Message complet"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "Fermer"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "Le message complet nest plus disponible."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "Le message complet ne contient aucun texte lisible."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "Le message complet na pas pu être chargé."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "Écouter"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Aller au plus récent"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Aller à la réponse la plus récente"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Actualiser"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "Copier le message"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "Ouvrir le message complet"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "Assistant"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Aller au plus récent"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Aller à la réponse la plus récente"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Actualiser"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "Exporter la transcription…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "Afficher le raisonnement et lactivité des outils"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "Afficher le raisonnement"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "Afficher lactivité des outils"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "%@ टोकन उपयोग किए गए"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "पूरा संदेश लोड हो रहा है…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "पूरा संदेश उपलब्ध नहीं है"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "पूरा संदेश"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "बंद करें"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "पूरा संदेश अब उपलब्ध नहीं है।"
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "पूरे संदेश में पढ़ने योग्य कोई टेक्स्ट नहीं है।"
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "पूरा संदेश लोड नहीं किया जा सका।"
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "सुनें"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "नवीनतम पर जाएँ"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "नवीनतम उत्तर पर जाएँ"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "रीफ़्रेश करें"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "संदेश कॉपी करें"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "पूरा संदेश खोलें"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "सहायक"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "नवीनतम पर जाएँ"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "नवीनतम उत्तर पर जाएँ"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "रीफ़्रेश करें"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "ट्रांसक्रिप्ट निर्यात करें…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "तर्क और टूल गतिविधि दिखाएँ"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "तर्क दिखाएँ"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "टूल गतिविधि दिखाएँ"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "%@ token telah digunakan"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "Memuat pesan lengkap…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "Pesan lengkap tidak tersedia"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "Pesan Lengkap"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "Tutup"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "Pesan lengkap sudah tidak tersedia."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "Pesan lengkap tidak memiliki teks yang dapat dibaca."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "Pesan lengkap tidak dapat dimuat."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "Dengarkan"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Lompat ke terbaru"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Lompat ke balasan terbaru"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Segarkan"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "Salin Pesan"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "Buka Pesan Lengkap"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "Asisten"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Lompat ke terbaru"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Lompat ke balasan terbaru"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Segarkan"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "Ekspor Transkrip…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "Tampilkan penalaran & aktivitas alat"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "Tampilkan Penalaran"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "Tampilkan Aktivitas Alat"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "%@ token utilizzati"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "Caricamento del messaggio completo…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "Messaggio completo non disponibile"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "Messaggio completo"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "Chiudi"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "Il messaggio completo non è più disponibile."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "Il messaggio completo non contiene testo leggibile."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "Impossibile caricare il messaggio completo."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "Ascolta"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Vai all'ultimo"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Vai all'ultima risposta"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Aggiorna"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "Copia messaggio"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "Apri il messaggio completo"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "Assistente"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Vai all'ultimo"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Vai all'ultima risposta"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Aggiorna"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "Esporta trascrizione…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "Mostra il ragionamento e l'attività degli strumenti"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "Mostra il ragionamento"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "Mostra l'attività degli strumenti"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "%@トークンを使用"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "メッセージ全文を読み込み中…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "メッセージ全文を利用できません"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "メッセージ全文"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "閉じる"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "メッセージ全文は利用できなくなりました。"
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "メッセージ全文に読み取れるテキストがありません。"
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "メッセージ全文を読み込めませんでした。"
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "聞く"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "最新に移動"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "最新の返信に移動"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "更新"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "メッセージをコピー"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "メッセージ全文を開く"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "アシスタント"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "最新に移動"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "最新の返信に移動"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "更新"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "トランスクリプトをエクスポート…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "推論とツールのアクティビティを表示"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "推論を表示"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "ツールのアクティビティを表示"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "%@개 토큰 사용됨"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "전체 메시지를 불러오는 중…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "전체 메시지를 사용할 수 없음"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "전체 메시지"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "닫기"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "전체 메시지를 더 이상 사용할 수 없습니다."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "전체 메시지에 읽을 수 있는 텍스트가 없습니다."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "전체 메시지를 불러올 수 없습니다."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "듣기"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "최신 항목으로 이동"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "최신 답글로 이동"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "새로 고침"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "메시지 복사"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "전체 메시지 열기"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "어시스턴트"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "최신 항목으로 이동"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "최신 답글로 이동"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "새로 고침"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "기록 내보내기…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "추론 및 도구 활동 표시"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "추론 보기"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "도구 활동 보기"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "%@ tokens gebruikt"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "Volledig bericht laden…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "Volledig bericht niet beschikbaar"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "Volledig bericht"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "Sluiten"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "Het volledige bericht is niet meer beschikbaar."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "Het volledige bericht bevat geen leesbare tekst."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "Het volledige bericht kon niet worden geladen."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "Luisteren"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Naar nieuwste springen"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Naar nieuwste antwoord springen"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Vernieuwen"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "Bericht kopiëren"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "Volledig bericht openen"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "Assistent"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Naar nieuwste springen"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Naar nieuwste antwoord springen"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Vernieuwen"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "Transcript exporteren…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "Redenering en toolactiviteit tonen"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "Redenering tonen"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "Toolactiviteit tonen"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "Wykorzystano %@ tokenów"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "Wczytywanie pełnej wiadomości…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "Pełna wiadomość jest niedostępna"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "Pełna wiadomość"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "Zamknij"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "Pełna wiadomość nie jest już dostępna."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "Pełna wiadomość nie zawiera tekstu możliwego do odczytania."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "Nie udało się wczytać pełnej wiadomości."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "Słuchaj"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Przejdź do najnowszych"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Przejdź do najnowszej odpowiedzi"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Odśwież"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "Kopiuj wiadomość"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "Otwórz pełną wiadomość"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "Asystent"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Przejdź do najnowszych"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Przejdź do najnowszej odpowiedzi"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Odśwież"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "Eksportuj transkrypcję…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "Pokaż tok rozumowania i aktywność narzędzi"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "Pokaż tok rozumowania"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "Pokaż aktywność narzędzi"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "%@ tokens usados"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "Carregando mensagem completa…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "Mensagem completa indisponível"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "Mensagem completa"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "Fechar"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "A mensagem completa não está mais disponível."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "A mensagem completa não contém texto legível."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "Não foi possível carregar a mensagem completa."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "Ouvir"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Ir para a mais recente"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Ir para a resposta mais recente"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Atualizar"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "Copiar mensagem"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "Abrir mensagem completa"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "Assistente"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Ir para a mais recente"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Ir para a resposta mais recente"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Atualizar"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "Exportar transcrição…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "Mostrar raciocínio e atividade das ferramentas"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "Mostrar raciocínio"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "Mostrar atividade das ferramentas"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "Использовано токенов: %@"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "Загрузка полного сообщения…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "Полное сообщение недоступно"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "Полное сообщение"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "Закрыть"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "Полное сообщение больше недоступно."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "В полном сообщении нет читаемого текста."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "Не удалось загрузить полное сообщение."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "Слушать"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Перейти к последнему"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Перейти к последнему ответу"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Обновить"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "Копировать сообщение"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "Открыть полное сообщение"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "Ассистент"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Перейти к последнему"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Перейти к последнему ответу"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Обновить"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "Экспорт транскрипта…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "Показывать ход рассуждений и действия инструментов"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "Показать ход рассуждений"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "Показать действия инструментов"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "%@ token används"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "Läser in hela meddelandet…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "Hela meddelandet är inte tillgängligt"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "Hela meddelandet"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "Stäng"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "Hela meddelandet är inte längre tillgängligt."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "Hela meddelandet saknar läsbar text."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "Det gick inte att läsa in hela meddelandet."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "Lyssna"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Hoppa till senaste"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Hoppa till senaste svar"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Uppdatera"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "Kopiera meddelande"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "Öppna hela meddelandet"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "Assistent"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Hoppa till senaste"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Hoppa till senaste svar"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Uppdatera"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "Exportera transkription…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "Visa resonemang och verktygsaktivitet"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "Visa resonemang"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "Visa verktygsaktivitet"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "ใช้โทเค็นไป %@ รายการ"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "กำลังโหลดข้อความฉบับเต็ม…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "ไม่สามารถดูข้อความฉบับเต็มได้"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "ข้อความฉบับเต็ม"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "ปิด"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "ข้อความฉบับเต็มไม่พร้อมใช้งานแล้ว"
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "ข้อความฉบับเต็มไม่มีข้อความที่อ่านได้"
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "ไม่สามารถโหลดข้อความฉบับเต็มได้"
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "ฟัง"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "ข้ามไปยังล่าสุด"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "ข้ามไปยังการตอบกลับล่าสุด"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "รีเฟรช"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "คัดลอกข้อความ"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "เปิดข้อความฉบับเต็ม"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "ผู้ช่วย"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "ข้ามไปยังล่าสุด"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "ข้ามไปยังการตอบกลับล่าสุด"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "รีเฟรช"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "ส่งออกสำเนาบทสนทนา…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "แสดงกระบวนการให้เหตุผลและการทำงานของเครื่องมือ"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "แสดงกระบวนการให้เหตุผล"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "แสดงกิจกรรมของเครื่องมือ"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "%@ token kullanıldı"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "Tam ileti yükleniyor…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "Tam ileti kullanılamıyor"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "Tam İleti"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "Kapat"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "Tam ileti artık kullanılamıyor."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "Tam iletide okunabilir metin yok."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "Tam ileti yüklenemedi."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "Dinle"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "En yeniye atla"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "En yeni yanıta atla"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Yenile"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "Mesajı Kopyala"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "Tam İletiyi Aç"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "Asistan"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "En yeniye atla"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "En yeni yanıta atla"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Yenile"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "Dökümü Dışa Aktar…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "Akıl yürütme ve araç etkinliğini göster"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "Akıl Yürütmeyi Göster"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "Araç Etkinliğini Göster"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "Використано токенів: %@"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "Завантаження повного повідомлення…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "Повідомлення повністю недоступне"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "Повне повідомлення"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "Закрити"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "Повне повідомлення більше недоступне."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "Повне повідомлення не містить тексту, який можна прочитати."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "Не вдалося завантажити повне повідомлення."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "Слухати"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Перейти до останнього"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Перейти до останньої відповіді"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Оновити"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "Копіювати повідомлення"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "Відкрити повне повідомлення"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "Асистент"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Перейти до останнього"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Перейти до останньої відповіді"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Оновити"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "Експортувати стенограму…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "Показувати міркування та дії інструментів"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "Показати міркування"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "Показати активність інструментів"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "Đã sử dụng %@ token"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "Đang tải toàn bộ tin nhắn…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "Không có toàn bộ tin nhắn"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "Toàn bộ tin nhắn"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "Đóng"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "Toàn bộ tin nhắn không còn khả dụng."
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "Toàn bộ tin nhắn không có văn bản có thể đọc được."
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "Không thể tải toàn bộ tin nhắn."
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "Nghe"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Chuyển đến mới nhất"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Chuyển đến phản hồi mới nhất"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Làm mới"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "Sao chép tin nhắn"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "Mở toàn bộ tin nhắn"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "Trợ lý"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "Chuyển đến mới nhất"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "Chuyển đến phản hồi mới nhất"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "Làm mới"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "Xuất Bản ghi…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "Hiển thị quá trình suy luận và hoạt động của công cụ"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "Hiển thị lập luận"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "Hiển thị hoạt động của công cụ"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "已使用 %@ 个 token"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "正在加载完整消息…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "完整消息不可用"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "完整消息"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "关闭"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "完整消息已不再可用。"
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "完整消息中没有可读文本。"
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "无法加载完整消息。"
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "聆听"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "跳转到最新"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "跳转到最新回复"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "刷新"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "复制消息"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "打开完整消息"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "助手"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "跳转到最新"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "跳转到最新回复"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "刷新"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "导出对话记录…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "显示推理和工具活动"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "显示推理过程"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "显示工具活动"
},
{
"id": "native.apple.4b24d792545e5086",
+63 -18
View File
@@ -22743,6 +22743,41 @@
"source": "%@ tokens used",
"translated": "已使用 %@ 個權杖"
},
{
"id": "native.apple.ccfd6ae994d82449",
"source": "Loading full message…",
"translated": "正在載入完整訊息…"
},
{
"id": "native.apple.669ad52de4a26b87",
"source": "Full message unavailable",
"translated": "無法取得完整訊息"
},
{
"id": "native.apple.6f79794ee74caf99",
"source": "Full Message",
"translated": "完整訊息"
},
{
"id": "native.apple.d648251591db5dec",
"source": "Close",
"translated": "關閉"
},
{
"id": "native.apple.ba3963204bda5e84",
"source": "The full message is no longer available.",
"translated": "完整訊息已無法取得。"
},
{
"id": "native.apple.8bb98bd86ae85c1c",
"source": "The full message has no readable text.",
"translated": "完整訊息中沒有可讀取的文字。"
},
{
"id": "native.apple.2f43669d87c0e26d",
"source": "The full message could not be loaded.",
"translated": "無法載入完整訊息。"
},
{
"id": "native.apple.2c865ac4a69645d3",
"source": "Widget unavailable",
@@ -23128,11 +23163,31 @@
"source": "Listen",
"translated": "聆聽"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "跳至最新內容"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "跳至最新回覆"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "重新整理"
},
{
"id": "native.apple.fe9f30f12f1dcfaf",
"source": "Copy Message",
"translated": "複製訊息"
},
{
"id": "native.apple.90bc8a8045e7017e",
"source": "Open Full Message",
"translated": "開啟完整訊息"
},
{
"id": "native.apple.b37ec7bd7dc1579a",
"source": "Reply",
@@ -23148,21 +23203,6 @@
"source": "Assistant",
"translated": "助理"
},
{
"id": "native.apple.f84b674ad395b694",
"source": "Jump to latest",
"translated": "跳至最新內容"
},
{
"id": "native.apple.429d825201b2cb85",
"source": "Jump to latest reply",
"translated": "跳至最新回覆"
},
{
"id": "native.apple.9ab586b85834705c",
"source": "Refresh",
"translated": "重新整理"
},
{
"id": "native.apple.28c2691c03030434",
"source": "Loading chat",
@@ -23374,9 +23414,14 @@
"translated": "匯出對話紀錄…"
},
{
"id": "native.apple.3294ababd29c4457",
"source": "Show reasoning & tool activity",
"translated": "顯示推理與工具活動"
"id": "native.apple.ebb130189022c7ec",
"source": "Show Reasoning",
"translated": "顯示推理過程"
},
{
"id": "native.apple.d0dba9aad550fa6e",
"source": "Show Tool Activity",
"translated": "顯示工具活動"
},
{
"id": "native.apple.4b24d792545e5086",
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -208,7 +208,7 @@ struct SwiftUIRenderSmokeTests {
let root = ChatStreamingAssistantBubble(
text: text,
markdownVariant: .standard,
showsAssistantTrace: false,
showsReasoning: false,
assistantName: "OpenClaw",
assistantAvatarText: "OC",
assistantAvatarTint: nil,
@@ -245,7 +245,7 @@ struct SwiftUIRenderSmokeTests {
style: .standard,
markdownVariant: .standard,
userAccent: nil,
showsAssistantTrace: false,
displayOptions: [],
assistantName: "OpenClaw",
assistantAvatarText: "OC",
assistantAvatarTint: nil,
@@ -18,6 +18,30 @@ private enum WebChatSwiftUILayout {
static let anchorPadding: CGFloat = 8
}
enum WebChatTracePreferences {
static func displayOptions(defaults: UserDefaults = .standard) -> OpenClawChatDisplayOptions {
if let legacyValue = defaults.object(
forKey: OpenClawChatWindowShell.assistantTraceDefaultsKey) as? Bool
{
for key in [
OpenClawChatWindowShell.assistantReasoningDefaultsKey,
OpenClawChatWindowShell.assistantToolActivityDefaultsKey,
] where defaults.object(forKey: key) == nil {
defaults.set(legacyValue, forKey: key)
}
}
var options: OpenClawChatDisplayOptions = []
if defaults.object(forKey: OpenClawChatWindowShell.assistantReasoningDefaultsKey) as? Bool ?? true {
options.insert(.reasoning)
}
if defaults.object(forKey: OpenClawChatWindowShell.assistantToolActivityDefaultsKey) as? Bool ?? true {
options.insert(.toolActivity)
}
return options
}
}
/// SwiftUI's native toolbar bridge may restore visible title chrome while it
/// installs toolbar items. Keep the full-window chat's titlebar merged.
private final class WebChatWindow: NSWindow {
@@ -89,6 +113,37 @@ struct MacGatewayChatTransport: OpenClawChatTransport {
agentID: target.agentID)
}
func requestFullMessage(sessionKey: String, messageID: String) async throws -> OpenClawChatMessage? {
let target = self.sessionTarget(for: sessionKey)
let request = try Self.fullMessageRequest(
sessionKey: target.sessionKey,
agentID: target.agentID,
messageID: messageID)
let data = try await GatewayConnection.shared.request(request)
let result = try JSONDecoder().decode(ChatMessageGetResult.self, from: data)
guard result.ok, let encodedMessage = result.message else { return nil }
return try JSONDecoder().decode(
OpenClawChatMessage.self,
from: JSONEncoder().encode(encodedMessage))
}
static func fullMessageRequest(
sessionKey: String,
agentID: String?,
messageID: String) throws -> OpenClawChatGatewayRequest
{
let params = ChatMessageGetParams(
sessionkey: sessionKey,
agentid: agentID,
messageid: messageID,
maxchars: 500_000)
let encoded = try JSONEncoder().encode(params)
return try OpenClawChatGatewayRequest(
method: "chat.message.get",
params: JSONDecoder().decode([String: AnyCodable].self, from: encoded),
timeoutMs: 15000)
}
func resolveInlineWidgetResource(
path: String,
replacing failedResource: OpenClawChatWidgetResource?) async -> OpenClawChatWidgetResource?
@@ -594,8 +649,10 @@ private struct MacChatSurface: View {
@State private var appState = AppStateStore.shared
@State private var talkController = TalkModeController.shared
@State private var audioInputCatalog = MacChatAudioInputCatalog()
@AppStorage(OpenClawChatWindowShell.assistantTraceDefaultsKey)
private var showsAssistantTrace = true
@AppStorage(OpenClawChatWindowShell.assistantReasoningDefaultsKey)
private var showsReasoning = WebChatTracePreferences.displayOptions().contains(.reasoning)
@AppStorage(OpenClawChatWindowShell.assistantToolActivityDefaultsKey)
private var showsToolActivity = WebChatTracePreferences.displayOptions().contains(.toolActivity)
private let isFullWindow: Bool
private let userAccent: Color?
@@ -622,7 +679,7 @@ private struct MacChatSurface: View {
OpenClawChatWindowShell(
viewModel: self.viewModel,
userAccent: self.userAccent,
showsAssistantTrace: self.showsAssistantTrace,
displayOptions: self.displayOptions,
emptyAssistantIntro: Self.emptyAssistantIntro,
emptyAssistantPrompts: Self.emptyAssistantPrompts,
talkControl: self.talkControl,
@@ -670,6 +727,13 @@ private struct MacChatSurface: View {
})
}
private var displayOptions: OpenClawChatDisplayOptions {
var options: OpenClawChatDisplayOptions = []
if self.showsReasoning { options.insert(.reasoning) }
if self.showsToolActivity { options.insert(.toolActivity) }
return options
}
private var voiceNoteControl: OpenClawChatVoiceNoteControl {
OpenClawChatVoiceNoteControl(
recorder: self.voiceNoteRecorder,
@@ -711,7 +775,7 @@ private struct MacChatSurface: View {
hasTalkControl: true,
hasSpeech: true,
hasVoiceNoteControl: true,
showsAssistantTrace: self.isFullWindow && self.showsAssistantTrace)
displayOptions: self.isFullWindow ? self.displayOptions : [])
}
#endif
}
@@ -721,7 +785,7 @@ struct MacChatSurfaceCapabilities: Equatable {
let hasTalkControl: Bool
let hasSpeech: Bool
let hasVoiceNoteControl: Bool
let showsAssistantTrace: Bool
let displayOptions: OpenClawChatDisplayOptions
}
#endif
@@ -1,3 +1,4 @@
import Foundation
import OpenClawChatUI
import OpenClawKit
import OpenClawProtocol
@@ -54,6 +55,33 @@ struct MacGatewayChatTransportMappingTests {
#expect(request.params["verboseLevel"]?.value as? String == "full")
}
@Test func `full message request uses generated gateway field names`() throws {
let request = try MacGatewayChatTransport.fullMessageRequest(
sessionKey: "global",
agentID: "reviewer",
messageID: "msg-42")
#expect(request.method == "chat.message.get")
#expect(request.params["sessionKey"]?.value as? String == "global")
#expect(request.params["agentId"]?.value as? String == "reviewer")
#expect(request.params["messageId"]?.value as? String == "msg-42")
#expect(request.params["maxChars"]?.value as? Int == 500_000)
}
@Test func `legacy trace preference migrates to independent defaults once`() throws {
let suiteName = "MacGatewayChatTransportMappingTests.\(UUID().uuidString)"
let defaults = try #require(UserDefaults(suiteName: suiteName))
defer { defaults.removePersistentDomain(forName: suiteName) }
defaults.set(false, forKey: OpenClawChatWindowShell.assistantTraceDefaultsKey)
#expect(WebChatTracePreferences.displayOptions(defaults: defaults).isEmpty)
#expect(defaults.object(forKey: OpenClawChatWindowShell.assistantReasoningDefaultsKey) as? Bool == false)
#expect(defaults.object(forKey: OpenClawChatWindowShell.assistantToolActivityDefaultsKey) as? Bool == false)
defaults.set(true, forKey: OpenClawChatWindowShell.assistantReasoningDefaultsKey)
#expect(WebChatTracePreferences.displayOptions(defaults: defaults) == [.reasoning])
}
@Test func `snapshot maps to health`() {
let snapshot = Snapshot(
presence: [],
@@ -42,14 +42,20 @@ struct WebChatSwiftUISmokeTests {
}
@Test func `window controller merges titlebar and keeps toolbar controls`() throws {
let traceKey = OpenClawChatWindowShell.assistantTraceDefaultsKey
let previousTraceValue = UserDefaults.standard.object(forKey: traceKey)
UserDefaults.standard.removeObject(forKey: traceKey)
let traceKeys = [
OpenClawChatWindowShell.assistantTraceDefaultsKey,
OpenClawChatWindowShell.assistantReasoningDefaultsKey,
OpenClawChatWindowShell.assistantToolActivityDefaultsKey,
]
let previousTraceValues = traceKeys.map { ($0, UserDefaults.standard.object(forKey: $0)) }
traceKeys.forEach { UserDefaults.standard.removeObject(forKey: $0) }
defer {
if let previousTraceValue {
UserDefaults.standard.set(previousTraceValue, forKey: traceKey)
} else {
UserDefaults.standard.removeObject(forKey: traceKey)
for (key, value) in previousTraceValues {
if let value {
UserDefaults.standard.set(value, forKey: key)
} else {
UserDefaults.standard.removeObject(forKey: key)
}
}
}
let controller = WebChatSwiftUIWindowController(
@@ -70,7 +76,7 @@ struct WebChatSwiftUISmokeTests {
#expect(capabilities.hasTalkControl)
#expect(capabilities.hasSpeech)
#expect(capabilities.hasVoiceNoteControl)
#expect(capabilities.showsAssistantTrace)
#expect(capabilities.displayOptions == .assistantTrace)
controller.show()
#expect(window.titleVisibility == .hidden)
@@ -0,0 +1,92 @@
import SwiftUI
struct ChatFullMessageReaderRequest: Identifiable, Sendable {
let sessionKey: String
let messageID: String
var id: String {
"\(self.sessionKey)\u{0}\(self.messageID)"
}
}
@MainActor
struct ChatFullMessageReader: View {
private enum Phase {
case loading
case loaded(String)
case failed(String)
}
let request: ChatFullMessageReaderRequest
let markdownVariant: ChatMarkdownVariant
let load: @MainActor @Sendable () async throws -> OpenClawChatMessage?
@Environment(\.dismiss) private var dismiss
@State private var phase: Phase = .loading
var body: some View {
NavigationStack {
Group {
switch self.phase {
case .loading:
VStack(spacing: 10) {
ProgressView()
Text("Loading full message…")
.font(OpenClawChatTypography.body)
.foregroundStyle(.secondary)
}
case let .loaded(markdown):
ScrollView {
ChatMarkdownRenderer(
text: markdown,
context: .assistant,
variant: self.markdownVariant,
font: OpenClawChatTypography.body,
textColor: OpenClawChatTheme.assistantText)
.textSelection(.enabled)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(20)
}
case let .failed(message):
ContentUnavailableView(
String(localized: "Full message unavailable"),
systemImage: "doc.text.magnifyingglass",
description: Text(message))
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.navigationTitle("Full Message")
.toolbar {
ToolbarItem(placement: .confirmationAction) {
Button("Close") { self.dismiss() }
}
}
}
#if os(macOS)
.frame(minWidth: 560, minHeight: 420)
#endif
.task(id: self.request.id) {
await self.loadMessage()
}
}
private func loadMessage() async {
self.phase = .loading
do {
guard let message = try await self.load() else {
self.phase = .failed(String(localized: "The full message is no longer available."))
return
}
let markdown = ChatMessageVisibleText.visibleText(in: message)
guard !markdown.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
self.phase = .failed(String(localized: "The full message has no readable text."))
return
}
self.phase = .loaded(markdown)
} catch is CancellationError {
return
} catch {
self.phase = .failed(String(localized: "The full message could not be loaded."))
}
}
}
@@ -206,7 +206,7 @@ struct ChatMessageBubble: View {
let style: OpenClawChatView.Style
let markdownVariant: ChatMarkdownVariant
let userAccent: Color?
let showsAssistantTrace: Bool
let displayOptions: OpenClawChatDisplayOptions
let assistantName: String?
let assistantAvatarText: String?
let assistantAvatarTint: Color?
@@ -253,7 +253,7 @@ struct ChatMessageBubble: View {
style: self.style,
markdownVariant: self.markdownVariant,
userAccent: self.userAccent,
showsAssistantTrace: self.showsAssistantTrace,
displayOptions: self.displayOptions,
isClean: self.isClean,
contextWindowTokens: self.contextWindowTokens,
inlineWidgetResolverReady: self.inlineWidgetResolverReady,
@@ -269,7 +269,7 @@ private struct ChatMessageBody: View {
let style: OpenClawChatView.Style
let markdownVariant: ChatMarkdownVariant
let userAccent: Color?
let showsAssistantTrace: Bool
let displayOptions: OpenClawChatDisplayOptions
let isClean: Bool
let contextWindowTokens: Int?
let inlineWidgetResolverReady: Bool
@@ -303,8 +303,8 @@ private struct ChatMessageBody: View {
private func messageContent(text: String, textColor: Color) -> some View {
VStack(alignment: .leading, spacing: 10) {
if self.isToolResultMessage, self.showsAssistantTrace {
if !text.isEmpty {
if self.isToolResultMessage {
if self.displayOptions.contains(.toolActivity), !text.isEmpty {
ToolResultCard(
title: self.toolResultTitle,
text: text,
@@ -322,7 +322,7 @@ private struct ChatMessageBody: View {
ChatAssistantTextBody(
text: text,
markdownVariant: self.markdownVariant,
includesThinking: self.showsAssistantTrace)
includesThinking: self.displayOptions.contains(.reasoning))
}
if self.showsLinkPreview, let previewURL = chatFirstPreviewURL(in: text) {
@@ -342,14 +342,14 @@ private struct ChatMessageBody: View {
resolveResource: self.inlineWidgetResourceResolver)
}
if self.showsAssistantTrace, !self.toolCalls.isEmpty {
if self.displayOptions.contains(.toolActivity), !self.toolCalls.isEmpty {
ForEach(self.toolCalls.indices, id: \.self) { idx in
ToolCallCard(
content: self.toolCalls[idx])
}
}
if self.showsAssistantTrace, !self.inlineToolResults.isEmpty {
if self.displayOptions.contains(.toolActivity), !self.inlineToolResults.isEmpty {
ForEach(self.inlineToolResults.indices, id: \.self) { idx in
let toolResult = self.inlineToolResults[idx]
let display = ToolDisplayRegistry.resolve(name: toolResult.name ?? "tool", args: nil)
@@ -855,7 +855,7 @@ extension View {
struct ChatStreamingAssistantBubble: View {
let text: String
let markdownVariant: ChatMarkdownVariant
let showsAssistantTrace: Bool
let showsReasoning: Bool
let assistantName: String?
let assistantAvatarText: String?
let assistantAvatarTint: Color?
@@ -876,7 +876,7 @@ struct ChatStreamingAssistantBubble: View {
ChatAssistantTextBody(
text: self.text,
markdownVariant: self.markdownVariant,
includesThinking: self.showsAssistantTrace,
includesThinking: self.showsReasoning,
isComplete: false)
}
.padding(self.isClean ? 4 : 12)
@@ -5,6 +5,11 @@ import Foundation
/// transcript exporter and the Listen action so exported and spoken text
/// always match the visible transcript.
enum ChatMessageVisibleText {
static func copyText(in message: OpenClawChatMessage) -> String {
let role = message.role.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
return role == "assistant" ? self.visibleText(in: message) : self.primaryText(in: message)
}
static func visibleText(in message: OpenClawChatMessage) -> String {
let text = self.primaryText(in: message)
let role = message.role.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
@@ -220,10 +220,14 @@ public struct OpenClawChatCanvasPreview: Codable, Hashable, Sendable {
public struct OpenClawChatMessage: Codable, Hashable, Identifiable, Sendable {
private struct OpenClawMetadata: Codable {
let id: String?
let idempotencyKey: String?
let truncated: Bool?
}
public var id: UUID = .init()
public var transcriptMessageID: String?
public var isTruncated = false
public let role: String
public let content: [OpenClawChatMessageContent]
public let timestamp: Double?
@@ -258,6 +262,8 @@ public struct OpenClawChatMessage: Codable, Hashable, Identifiable, Sendable {
role: String,
content: [OpenClawChatMessageContent],
timestamp: Double?,
transcriptMessageID: String? = nil,
isTruncated: Bool = false,
idempotencyKey: String? = nil,
toolCallId: String? = nil,
toolName: String? = nil,
@@ -266,6 +272,8 @@ public struct OpenClawChatMessage: Codable, Hashable, Identifiable, Sendable {
errorMessage: String? = nil)
{
self.id = id
self.transcriptMessageID = transcriptMessageID
self.isTruncated = isTruncated
self.role = role
self.content = content
self.timestamp = timestamp
@@ -295,6 +303,7 @@ public struct OpenClawChatMessage: Codable, Hashable, Identifiable, Sendable {
let decodedErrorMessage = try container.decodeIfPresent(String.self, forKey: .errorMessage)
self.role = decodedRole
self.transcriptMessageID = decodedOpenClaw?.id
self.timestamp = decodedTimestamp
self.idempotencyKey = decodedIdempotencyKey
self.toolCallId = decodedToolCallId
@@ -352,6 +361,9 @@ public struct OpenClawChatMessage: Codable, Hashable, Identifiable, Sendable {
content: nil)
}
self.content = decodedContent + audioAttachments
self.isTruncated = decodedOpenClaw?.truncated == true || decodedContent.contains { content in
content.text?.contains(Self.transcriptTruncationMarker) == true
}
}
static func displayText(
@@ -388,11 +400,20 @@ public struct OpenClawChatMessage: Codable, Hashable, Identifiable, Sendable {
}
private static let streamErrorFallbackText = "[assistant turn failed before producing content]"
private static let transcriptTruncationMarker = "\n...(truncated)..."
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.role, forKey: .role)
try container.encodeIfPresent(self.timestamp, forKey: .timestamp)
if self.transcriptMessageID != nil || self.isTruncated {
try container.encode(
OpenClawMetadata(
id: self.transcriptMessageID,
idempotencyKey: nil,
truncated: self.isTruncated ? true : nil),
forKey: .openClaw)
}
try container.encodeIfPresent(self.idempotencyKey, forKey: .idempotencyKey)
try container.encodeIfPresent(self.toolCallId, forKey: .toolCallId)
try container.encodeIfPresent(self.toolName, forKey: .toolName)
@@ -265,6 +265,7 @@ public protocol OpenClawChatTransport: Sendable {
worktree: Bool?) async throws -> OpenClawChatCreateSessionResponse
func requestHistory(sessionKey: String) async throws -> OpenClawChatHistoryPayload
func requestFullMessage(sessionKey: String, messageID: String) async throws -> OpenClawChatMessage?
func listModels() async throws -> [OpenClawChatModelChoice]
var supportsSlashCommandCatalog: Bool { get }
func listCommands(sessionKey: String) async throws -> [OpenClawChatCommandChoice]
@@ -331,6 +332,10 @@ public protocol OpenClawChatTransport: Sendable {
}
extension OpenClawChatTransport {
public func requestFullMessage(sessionKey _: String, messageID _: String) async throws -> OpenClawChatMessage? {
nil
}
public func resolveInlineWidgetResource(
path: String,
replacing failedResource: OpenClawChatWidgetResource?) async -> OpenClawChatWidgetResource?
@@ -49,6 +49,22 @@ func chatReaderScrollReleasesFollow(_ phase: ScrollPhase) -> Bool {
}
}
public struct OpenClawChatDisplayOptions: OptionSet, Sendable {
public let rawValue: UInt8
public init(rawValue: UInt8) {
self.rawValue = rawValue
}
public static let reasoning = Self(rawValue: 1 << 0)
public static let toolActivity = Self(rawValue: 1 << 1)
public static let assistantTrace: Self = [.reasoning, .toolActivity]
public static func assistantTrace(_ isVisible: Bool) -> Self {
isVisible ? .assistantTrace : []
}
}
@MainActor
public struct OpenClawChatView: View {
public enum Style {
@@ -83,12 +99,13 @@ public struct OpenClawChatView: View {
@State private var followTarget: ScrollFollowTarget? = .latest
@State private var isAtLiveEdge = true
@State private var isUserScrolling = false
@State private var fullMessageRequest: ChatFullMessageReaderRequest?
private let showsSessionSwitcher: Bool
private let drawsBackground: Bool
private let style: Style
private let markdownVariant: ChatMarkdownVariant
private let userAccent: Color?
private let showsAssistantTrace: Bool
private let displayOptions: OpenClawChatDisplayOptions
private let assistantName: String?
private let assistantAvatarText: String?
private let assistantAvatarTint: Color?
@@ -134,6 +151,7 @@ public struct OpenClawChatView: View {
#endif
}
/// `showsAssistantTrace` remains as a source-compatible convenience that sets both display options.
public init(
viewModel: OpenClawChatViewModel,
drawsBackground: Bool = true,
@@ -141,6 +159,7 @@ public struct OpenClawChatView: View {
style: Style = .standard,
markdownVariant: ChatMarkdownVariant = .standard,
userAccent: Color? = nil,
displayOptions: OpenClawChatDisplayOptions? = nil,
showsAssistantTrace: Bool = false,
assistantName: String? = nil,
assistantAvatarText: String? = nil,
@@ -162,7 +181,7 @@ public struct OpenClawChatView: View {
self.style = style
self.markdownVariant = markdownVariant
self.userAccent = userAccent
self.showsAssistantTrace = showsAssistantTrace
self.displayOptions = displayOptions ?? .assistantTrace(showsAssistantTrace)
self.assistantName = assistantName
self.assistantAvatarText = assistantAvatarText
self.assistantAvatarTint = assistantAvatarTint
@@ -189,6 +208,16 @@ public struct OpenClawChatView: View {
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
.onAppear { self.viewModel.load() }
.sheet(item: self.$fullMessageRequest) { request in
ChatFullMessageReader(
request: request,
markdownVariant: self.markdownVariant,
load: {
try await self.viewModel.transport.requestFullMessage(
sessionKey: request.sessionKey,
messageID: request.messageID)
})
}
}
@ViewBuilder
@@ -391,7 +420,7 @@ public struct OpenClawChatView: View {
.equatable()
}
if !self.viewModel.pendingToolCalls.isEmpty {
if self.displayOptions.contains(.toolActivity), !self.viewModel.pendingToolCalls.isEmpty {
ChatPendingToolsBubble(
toolCalls: self.viewModel.pendingToolCalls,
isClean: self.composerChrome == .clean)
@@ -403,7 +432,7 @@ public struct OpenClawChatView: View {
ChatStreamingAssistantBubble(
text: text,
markdownVariant: self.markdownVariant,
showsAssistantTrace: self.showsAssistantTrace,
showsReasoning: self.displayOptions.contains(.reasoning),
assistantName: self.assistantName,
assistantAvatarText: self.assistantAvatarText,
assistantAvatarTint: self.assistantAvatarTint,
@@ -423,7 +452,7 @@ public struct OpenClawChatView: View {
style: self.style,
markdownVariant: self.markdownVariant,
userAccent: self.userAccent,
showsAssistantTrace: self.showsAssistantTrace,
displayOptions: self.displayOptions,
assistantName: self.assistantName,
assistantAvatarText: self.assistantAvatarText,
assistantAvatarTint: self.assistantAvatarTint,
@@ -449,6 +478,7 @@ public struct OpenClawChatView: View {
.contextMenu {
self.copyMessageButton(for: msg)
self.replyMessageButton(for: msg)
self.openFullMessageButton(for: msg)
if outboxState.isFailed {
Button {
self.viewModel.retryOutboxMessage(msg.id)
@@ -488,7 +518,9 @@ public struct OpenClawChatView: View {
}
.frame(maxWidth: .infinity, alignment: .leading)
.contextMenu {
self.copyMessageButton(for: msg)
self.replyMessageButton(for: msg)
self.openFullMessageButton(for: msg)
Button {
if speech.isActive(msg.id) {
speech.stop()
@@ -516,6 +548,7 @@ public struct OpenClawChatView: View {
.contextMenu {
self.copyMessageButton(for: msg)
self.replyMessageButton(for: msg)
self.openFullMessageButton(for: msg)
}
}
}
@@ -539,59 +572,6 @@ public struct OpenClawChatView: View {
}
}
@ViewBuilder
private func copyMessageButton(for message: OpenClawChatMessage) -> some View {
let text = self.primaryText(in: message)
if !text.isEmpty {
Button {
Self.copyToClipboard(text)
} label: {
Label {
Text("Copy Message")
.font(OpenClawChatTypography.body)
} icon: {
Image(systemName: "doc.on.doc")
}
}
}
}
@ViewBuilder
private func replyMessageButton(for message: OpenClawChatMessage) -> some View {
let role = message.role.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
let text = ChatReplyQuote.targetText(ChatMessageVisibleText.visibleText(in: message))
if role == "user" || role == "assistant", !text.isEmpty {
Button {
self.viewModel.setReplyTarget(
messageID: message.id,
text: text,
senderLabel: self.replySenderLabel(forRole: role))
} label: {
Label {
Text(String(localized: "Reply"))
.font(OpenClawChatTypography.body)
} icon: {
Image(systemName: "arrowshape.turn.up.left")
}
}
}
}
private func replySenderLabel(forRole role: String) -> String {
guard role == "assistant" else { return String(localized: "You") }
let name = self.assistantName?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
return name.isEmpty ? String(localized: "Assistant") : name
}
private static func copyToClipboard(_ text: String) {
#if os(macOS)
NSPasteboard.general.clearContents()
NSPasteboard.general.setString(text, forType: .string)
#else
UIPasteboard.general.string = text
#endif
}
private var visibleMessages: [OpenClawChatMessage] {
let base: [OpenClawChatMessage]
if self.style == .onboarding {
@@ -700,12 +680,14 @@ public struct OpenClawChatView: View {
private var hasVisibleStreamingAssistantText: Bool {
guard let text = self.viewModel.streamingAssistantText else { return false }
return AssistantTextParser.hasVisibleContent(in: text, includeThinking: self.showsAssistantTrace)
return AssistantTextParser.hasVisibleContent(
in: text,
includeThinking: self.displayOptions.contains(.reasoning))
}
private var hasVisibleTransientContent: Bool {
self.viewModel.hasBlockingRunActivity ||
!self.viewModel.pendingToolCalls.isEmpty ||
(self.displayOptions.contains(.toolActivity) && !self.viewModel.pendingToolCalls.isEmpty) ||
self.hasVisibleStreamingAssistantText
}
@@ -883,6 +865,18 @@ public struct OpenClawChatView: View {
}
}
private func dismissKeyboardIfNeeded() {
#if canImport(UIKit)
UIApplication.shared.sendAction(
#selector(UIResponder.resignFirstResponder),
to: nil,
from: nil,
for: nil)
#endif
}
}
extension OpenClawChatView {
private func mergeToolResults(in messages: [OpenClawChatMessage]) -> [OpenClawChatMessage] {
var result: [OpenClawChatMessage] = []
result.reserveCapacity(messages.count)
@@ -925,6 +919,8 @@ public struct OpenClawChatView: View {
role: last.role,
content: content,
timestamp: last.timestamp,
transcriptMessageID: last.transcriptMessageID,
isTruncated: last.isTruncated,
idempotencyKey: last.idempotencyKey,
toolCallId: last.toolCallId,
toolName: last.toolName,
@@ -943,29 +939,29 @@ public struct OpenClawChatView: View {
}
private func shouldDisplayMessage(_ message: OpenClawChatMessage) -> Bool {
let primaryText = self.primaryText(in: message)
if self.hasInlineAttachments(in: message) {
return true
}
let primaryText = self.primaryText(in: message)
if self.isToolResultMessage(message) {
return self.displayOptions.contains(.toolActivity) && !primaryText.isEmpty
}
if !primaryText.isEmpty {
if message.role.lowercased() == "user" {
return true
}
if AssistantTextParser.hasVisibleContent(in: primaryText, includeThinking: self.showsAssistantTrace) {
if AssistantTextParser.hasVisibleContent(
in: primaryText,
includeThinking: self.displayOptions.contains(.reasoning))
{
return true
}
}
guard self.showsAssistantTrace else {
return false
}
if self.isToolResultMessage(message) {
return !primaryText.isEmpty
}
return !self.toolCalls(in: message).isEmpty || !self.inlineToolResults(in: message).isEmpty
return self.displayOptions.contains(.toolActivity) &&
(!self.toolCalls(in: message).isEmpty || !self.inlineToolResults(in: message).isEmpty)
}
private func primaryText(in message: OpenClawChatMessage) -> String {
@@ -1026,13 +1022,79 @@ public struct OpenClawChatView: View {
self.primaryText(in: message)
}
private func dismissKeyboardIfNeeded() {
#if canImport(UIKit)
UIApplication.shared.sendAction(
#selector(UIResponder.resignFirstResponder),
to: nil,
from: nil,
for: nil)
@ViewBuilder
private func copyMessageButton(for message: OpenClawChatMessage) -> some View {
let text = ChatMessageVisibleText.copyText(in: message)
if !text.isEmpty {
Button {
Self.copyToClipboard(text)
} label: {
Label {
Text("Copy Message")
.font(OpenClawChatTypography.body)
} icon: {
Image(systemName: "doc.on.doc")
}
}
}
}
@ViewBuilder
private func openFullMessageButton(for message: OpenClawChatMessage) -> some View {
let role = message.role.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
if role == "assistant",
message.isTruncated,
let messageID = message.transcriptMessageID?.trimmingCharacters(in: .whitespacesAndNewlines),
!messageID.isEmpty
{
Button {
self.fullMessageRequest = ChatFullMessageReaderRequest(
sessionKey: self.viewModel.sessionKey,
messageID: messageID)
} label: {
Label {
Text("Open Full Message")
.font(OpenClawChatTypography.body)
} icon: {
Image(systemName: "doc.text.magnifyingglass")
}
}
}
}
@ViewBuilder
private func replyMessageButton(for message: OpenClawChatMessage) -> some View {
let role = message.role.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
let text = ChatReplyQuote.targetText(ChatMessageVisibleText.visibleText(in: message))
if role == "user" || role == "assistant", !text.isEmpty {
Button {
self.viewModel.setReplyTarget(
messageID: message.id,
text: text,
senderLabel: self.replySenderLabel(forRole: role))
} label: {
Label {
Text(String(localized: "Reply"))
.font(OpenClawChatTypography.body)
} icon: {
Image(systemName: "arrowshape.turn.up.left")
}
}
}
}
private func replySenderLabel(forRole role: String) -> String {
guard role == "assistant" else { return String(localized: "You") }
let name = self.assistantName?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
return name.isEmpty ? String(localized: "Assistant") : name
}
fileprivate static func copyToClipboard(_ text: String) {
#if os(macOS)
NSPasteboard.general.clearContents()
NSPasteboard.general.setString(text, forType: .string)
#else
UIPasteboard.general.string = text
#endif
}
}
@@ -9,7 +9,9 @@ import UniformTypeIdentifiers
/// window experience.
@MainActor
public struct OpenClawChatWindowShell: View {
public static let assistantTraceDefaultsKey = "openclaw.webchat.showAssistantTrace"
public nonisolated static let assistantTraceDefaultsKey = "openclaw.webchat.showAssistantTrace"
public nonisolated static let assistantReasoningDefaultsKey = "openclaw.webchat.showAssistantReasoning"
public nonisolated static let assistantToolActivityDefaultsKey = "openclaw.webchat.showAssistantToolActivity"
@State private var viewModel: OpenClawChatViewModel
@State private var sessionQuery = ""
@@ -19,16 +21,18 @@ public struct OpenClawChatWindowShell: View {
@State private var renameSessionKey: String?
@State private var renameText = ""
private let userAccent: Color?
private let showsAssistantTrace: Bool
private let displayOptions: OpenClawChatDisplayOptions
private let emptyAssistantIntro: String?
private let emptyAssistantPrompts: [OpenClawChatView.StarterPrompt]
private let talkControl: OpenClawChatTalkControl?
private let voiceNoteControl: OpenClawChatVoiceNoteControl?
private let speech: OpenClawChatSpeechController?
/// `showsAssistantTrace` remains as a source-compatible convenience that sets both display options.
public init(
viewModel: OpenClawChatViewModel,
userAccent: Color? = nil,
displayOptions: OpenClawChatDisplayOptions? = nil,
showsAssistantTrace: Bool = false,
emptyAssistantIntro: String? = nil,
emptyAssistantPrompts: [OpenClawChatView.StarterPrompt] = [],
@@ -38,7 +42,7 @@ public struct OpenClawChatWindowShell: View {
{
_viewModel = State(initialValue: viewModel)
self.userAccent = userAccent
self.showsAssistantTrace = showsAssistantTrace
self.displayOptions = displayOptions ?? .assistantTrace(showsAssistantTrace)
self.emptyAssistantIntro = emptyAssistantIntro
self.emptyAssistantPrompts = emptyAssistantPrompts
self.talkControl = talkControl
@@ -57,7 +61,7 @@ public struct OpenClawChatWindowShell: View {
viewModel: self.viewModel,
drawsBackground: false,
userAccent: self.userAccent,
showsAssistantTrace: self.showsAssistantTrace,
displayOptions: self.displayOptions,
composerChrome: .clean,
emptyAssistantIntro: self.emptyAssistantIntro,
emptyAssistantPrompts: self.emptyAssistantPrompts,
@@ -378,17 +382,29 @@ public struct OpenClawChatWindowShell: View {
.disabled(self.viewModel.messages.isEmpty)
Toggle(isOn: Binding(
get: { self.showsAssistantTrace },
get: { self.displayOptions.contains(.reasoning) },
set: {
UserDefaults.standard.set(
$0,
forKey: Self.assistantTraceDefaultsKey)
forKey: Self.assistantReasoningDefaultsKey)
})) {
chatWindowActionLabel(
"Show reasoning & tool activity",
"Show Reasoning",
systemImage: "brain.head.profile")
}
Toggle(isOn: Binding(
get: { self.displayOptions.contains(.toolActivity) },
set: {
UserDefaults.standard.set(
$0,
forKey: Self.assistantToolActivityDefaultsKey)
})) {
chatWindowActionLabel(
"Show Tool Activity",
systemImage: "hammer")
}
Divider()
Button {
@@ -42,6 +42,56 @@ struct ChatMessageVisibleTextTests {
#expect(ChatMessageVisibleText.visibleText(in: message) == "What is <final>up</final>?")
}
@Test func `assistant copy excludes thinking while user copy stays exact`() {
let assistant = OpenClawChatMessage(
role: "assistant",
content: [textContent("<think>private reasoning</think>\nVisible **answer**")],
timestamp: 1)
let user = OpenClawChatMessage(
role: "user",
content: [textContent("Keep <think>this literal tag</think>")],
timestamp: 1)
#expect(ChatMessageVisibleText.copyText(in: assistant) == "Visible **answer**")
#expect(ChatMessageVisibleText.copyText(in: user) == "Keep <think>this literal tag</think>")
}
@Test func `history decode retains transcript identity and truncation signals`() throws {
let metadata = try JSONDecoder().decode(
OpenClawChatMessage.self,
from: Data(#"{"role":"assistant","content":"short","__openclaw":{"id":"msg-1","truncated":true}}"#.utf8))
let marker = try JSONDecoder().decode(
OpenClawChatMessage.self,
from: Data(#"{"role":"assistant","content":"short\n...(truncated)...","__openclaw":{"id":"msg-2"}}"#.utf8))
#expect(metadata.transcriptMessageID == "msg-1")
#expect(metadata.isTruncated)
#expect(marker.transcriptMessageID == "msg-2")
#expect(marker.isTruncated)
}
@Test func `transcript metadata survives message coding round trip`() throws {
let original = OpenClawChatMessage(
role: "assistant",
content: [textContent("short\n...(truncated)...")],
timestamp: 1,
transcriptMessageID: "msg-round-trip",
isTruncated: true)
let decoded = try JSONDecoder().decode(
OpenClawChatMessage.self,
from: JSONEncoder().encode(original))
#expect(decoded.transcriptMessageID == "msg-round-trip")
#expect(decoded.isTruncated)
}
@Test func `legacy trace mapping sets both independent display options`() {
#expect(OpenClawChatDisplayOptions.assistantTrace(true) == [.reasoning, .toolActivity])
#expect(OpenClawChatDisplayOptions.assistantTrace(false).isEmpty)
#expect(OpenClawChatDisplayOptions.reasoning != .toolActivity)
}
@Test func `has visible text ignores tool blank and thinking only messages`() {
let toolOnly = OpenClawChatMessage(
role: "assistant",
+3 -3
View File
@@ -10,8 +10,8 @@ The macOS menu bar app embeds the WebChat UI as a native SwiftUI view. It connec
The full chat window is a native split view:
- **Sessions sidebar**: searchable session list with pinned and recent sections. Spawned child sessions nest beneath their parent when the Gateway provides hierarchy metadata; collapsed parents summarize running, failed, and unread descendants. Context menus support rename, pin, fork, read/unread, archive/restore, copy session key, and delete. A toolbar button (or Cmd-N) creates a real new session via `sessions.create`.
- **Window toolbar**: context-usage ring (tokens and session cost, with a compact action), thinking-level picker, model picker, and a session actions menu. The menu can rename or fork the current session and update its pin, read, or archive state. **Sessions…** (Shift-Cmd-S) opens the Active/Archived manager for gateway search, rename, pin, archive, and restore. The same menu can show or hide assistant reasoning and tool activity; this is on by default and remembered across launches.
- **Transcript and composer**: assistant messages render as plain text with an avatar, user messages as accent bubbles. Empty chats offer desktop starter prompts. Typing `/` opens slash-command autocomplete backed by `commands.list`, with arrow/Tab/Return/Escape keyboard navigation. Right-click a message to copy it, or use **Listen** for gateway TTS with a local speech fallback.
- **Window toolbar**: context-usage ring (tokens and session cost, with a compact action), thinking-level picker, model picker, and a session actions menu. The menu can rename or fork the current session and update its pin, read, or archive state. **Sessions…** (Shift-Cmd-S) opens the Active/Archived manager for gateway search, rename, pin, archive, and restore. Separate menu checkmarks show or hide assistant reasoning and tool activity; both are on by default and remembered across launches.
- **Transcript and composer**: assistant messages render as plain text with an avatar, user messages as accent bubbles. Empty chats offer desktop starter prompts. Typing `/` opens slash-command autocomplete backed by `commands.list`, with arrow/Tab/Return/Escape keyboard navigation. Right-click a message to copy its visible Markdown without hidden reasoning. Truncated assistant messages also offer **Open Full Message**, which loads a selectable Markdown reader. Use **Listen** for gateway TTS with a local speech fallback.
- **Voice controls**: the composer can start or stop the existing macOS Talk Mode without replacing its menu-bar overlay. While Talk Mode is active, the composer shows its listening/thinking/speaking state, live audio activity, and an expandable rolling transcript. Right-click the Talk button to choose **System Default** or a connected microphone; this is the same microphone selection used by Voice Wake and push-to-talk. If a selected microphone disconnects, the active Talk session falls back to the system default and tries the selection again the next time Talk Mode starts. A separate microphone action records a voice note when Talk Mode does not own audio capture.
The anchored compact chat panel from the menu bar keeps the compact single-column layout with inline pickers, starter prompts, Talk Mode, voice notes, and Listen. Assistant reasoning and tool activity remain hidden in this compact surface.
@@ -46,7 +46,7 @@ Disable the feature entirely with **Settings → General → Quick Chat**; the s
## How it is wired
- Data plane: Gateway WS methods `chat.history`, `chat.send`, `chat.abort`, `chat.inject`, and events `chat`, `agent`, `presence`, `tick`, `health`.
- Data plane: Gateway WS methods `chat.history`, `chat.message.get`, `chat.send`, `chat.abort`, `chat.inject`, and events `chat`, `agent`, `presence`, `tick`, `health`.
- `chat.history` returns a display-normalized transcript: inline directive tags are stripped from visible text, plain-text tool-call XML payloads (`<tool_call>`, `<function_call>`, `<tool_calls>`, `<function_calls>`, including truncated blocks) and leaked model control tokens are stripped, pure silent-token assistant rows such as exact `NO_REPLY`/`no_reply` are omitted, and oversized rows can be replaced with a truncated placeholder.
- Session: defaults to the primary session as above; the UI can switch between sessions.
- Unread state: after a session activates and its live history loads successfully, the app clears that session's unread marker. Failed history loads do not clear it; a transient patch failure retries on the next activation.