+ {display.text}
+
+ );
+ case "file_diff":
+ return (
+ {display.taskDescription}
+ ) : null} + {display.result && display.result.trim().length > 0 ? ( +
+ {preview.fileName}
+
+ {preview.kind === "diff" && preview.replaceAll ? (
+
+ {step.name || "инструмент"}
+
+
+ $
+ {step.command}
+
+ ) : isRenderableArgs(argsForDisplay) ? (
+
+ {part.name || "—"}
+
+
+ }
+ meta={
+
+ {part.name || "—"}
+
+
+ }
+ >
+
+ {text}
+
+ );
+}
+
+/** Copy-to-clipboard icon button, matching the chat bubble affordance. */
+export function CopyButton({ text }: { text: string }) {
+ const [copied, setCopied] = useState(false);
+ return (
+
+ );
+}
diff --git a/apps/web/src/ru-fork/advanced-chat/useTranscriptSubscription.ts b/apps/web/src/ru-fork/advanced-chat/useTranscriptSubscription.ts
new file mode 100644
index 00000000000..a4fcfbfaad3
--- /dev/null
+++ b/apps/web/src/ru-fork/advanced-chat/useTranscriptSubscription.ts
@@ -0,0 +1,53 @@
+// ru-fork: advanced chat mode — subscribe to the server's qwen-transcript stream for
+// a thread and keep the records in local state. Self-contained: reuses the exported
+// environment-connection registry (no store.ts / service.ts changes). Re-attaches if
+// the environment connection object is replaced (full reconnect).
+import type { EnvironmentId, ThreadId, TranscriptRecord } from "@t3tools/contracts";
+import { useEffect, useState } from "react";
+
+import {
+ readEnvironmentConnection,
+ subscribeEnvironmentConnections,
+} from "~/environments/runtime/service";
+
+export function useTranscriptSubscription(
+ environmentId: EnvironmentId | undefined,
+ threadId: ThreadId | undefined,
+ enabled: boolean,
+): ReadonlyArray