fix(studio): System-AI test-connection error is copyable
Some checks failed
Security / Security check (push) Failing after 1s

The System-AI editor rendered its failure (test connection, save, model
pull) as a bare Text(_error) — selectable-but-not-copyable, the exact
thing the operator needs to paste back. Route it through ChainErrorBox
(selectable + one-tap copy button), and show a failed test result via
ChainErrorBox too instead of a plain SelectableText.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
flemming-it 2026-06-19 01:52:52 +02:00
parent 8724b19234
commit 7f59334176

View file

@ -11,6 +11,7 @@ import '../data/hub.dart';
import '../l10n/app_localizations.dart';
import '../theme/theme.dart';
import '../theme/tokens.dart';
import 'chain_error_box.dart';
import 'chain_pill.dart';
/// Provider preset metadata kept in sync with
@ -459,12 +460,10 @@ class _FaiSystemAiEditorState extends State<ChainSystemAiEditor> {
],
if (_error != null) ...[
const SizedBox(height: ChainSpace.md),
Text(
_error!,
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.error,
),
),
// Copyable every error the operator sees must be
// selectable + one-tap copyable (ChainErrorBox), never
// a bare Text they can't paste back.
ChainErrorBox(text: _error!, isError: true, maxHeight: 200),
],
if (_testResult != null) ...[
const SizedBox(height: ChainSpace.md),
@ -650,10 +649,17 @@ class _TestResultPanel extends StatelessWidget {
],
),
const SizedBox(height: 4),
// Success the reply preview (selectable). Failure the
// raw error in a ChainErrorBox with an explicit copy button,
// so the operator can paste the exact failure back.
if (ok)
SelectableText(
ok ? l.systemAiReplyPrefix(result.text) : result.text,
style: ChainTheme.mono(size: 11, color: theme.colorScheme.onSurface),
),
l.systemAiReplyPrefix(result.text),
style:
ChainTheme.mono(size: 11, color: theme.colorScheme.onSurface),
)
else
ChainErrorBox(text: result.text, isError: true, maxHeight: 200),
if (!ok && result.fixHint(l).isNotEmpty) ...[
const SizedBox(height: ChainSpace.xs),
Text(