The-Agency/lib/ui/widgets/chat/bubbles/tools/tool_bubble_base.dart

145 lines
3.7 KiB
Dart

import "package:provider/provider.dart";
import "package:shadcn_flutter/shadcn_flutter.dart";
import "../../../../providers/chat_provider.dart";
import "../permission_decision.dart";
class ToolBubbleBase extends StatelessWidget {
const ToolBubbleBase({
super.key,
required this.toolName,
required this.icon,
this.detail,
this.body,
this.result,
this.isPendingPermission = false,
});
final String toolName;
final IconData icon;
final String? detail;
final Widget? body;
final String? result;
final bool isPendingPermission;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
OutlinedContainer(
clipBehavior: Clip.antiAlias,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
IntrinsicHeight(
child: Row(
children: [
Container(
color: theme.colorScheme.primary.scaleAlpha(0.5),
padding: EdgeInsets.symmetric(
horizontal: 20,
vertical: 12,
),
child: Row(
children: [
Icon(icon).iconSmall,
Gap(8),
Text(
toolName,
).textSmall,
],
),
),
VerticalDivider(),
if (detail != null)...[
Gap(16),
Text(
detail!,
).mono.xSmall
]
],
),
),
if (body != null) ...[
Divider(),
body!,
],
if (result != null) ...[
Divider(),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
child: SelectableText(
"\u200B${result!}",
style: TextStyle(
color: theme.colorScheme.mutedForeground,
),
).xSmall.mono,
)
]
],
),
),
if (isPendingPermission) ...[
Gap(8),
Row(
children: [
Expanded(
child: Button.outline(
leading: Icon(LucideIcons.check).iconSmall,
onPressed: () => context.read<ChatProvider>().resolvePermission(PermissionDecision.allowOnce),
child: Text("Allow").small,
),
),
Gap(8),
Expanded(
child: Button.outline(
leading: Icon(LucideIcons.checkCheck).iconSmall,
onPressed: () => context.read<ChatProvider>().resolvePermission(PermissionDecision.allowAlways),
child: Text("Allow always").small,
),
),
Gap(8),
Expanded(
child: Button.destructive(
leading: Icon(LucideIcons.x).iconSmall,
onPressed: () => context.read<ChatProvider>().resolvePermission(PermissionDecision.reject),
child: Text("Reject").small,
),
),
],
),
],
],
);
}
}