refactor: clean CLI taxonomy — canonical subcommands, merged memory.update, no aliases
- calendar: split write → create/read/update/delete/share - contacts: rename lookup → read - memory: merge write+forget → update (unified action field in operations) - Remove all alias/normalization logic from adapter and handlers - Update tool_postprocessor ui_hints builders to canonical keys - Remove frontend legacy TOOL_CALL_START/ARGS/END events and ToolCallItem - Update SKILL.md files and protocol docs - Update tests and settings screens
This commit is contained in:
@@ -4,9 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:lucide_icons/lucide_icons.dart';
|
||||
import 'package:social_app/core/chat/chat_list_item.dart';
|
||||
|
||||
import '../../../../core/l10n/l10n.dart';
|
||||
import '../../../../core/theme/design_tokens.dart';
|
||||
import '../../../../core/utils/tool_name_localizer.dart';
|
||||
import '../../../../shared/widgets/app_loading_indicator.dart';
|
||||
import '../../../../shared/widgets/ui_schema/ui_schema_renderer.dart';
|
||||
|
||||
@@ -21,18 +19,28 @@ const _toolResultWidthFactor = 0.88;
|
||||
const _iconSize = AppSpacing.xxl;
|
||||
|
||||
class HomeChatItemRenderer {
|
||||
static Widget build(BuildContext context, ChatListItem item) {
|
||||
static Widget build(
|
||||
BuildContext context,
|
||||
ChatListItem item, {
|
||||
ValueChanged<String>? onSuggestedActionTap,
|
||||
}) {
|
||||
switch (item.type) {
|
||||
case ChatItemType.message:
|
||||
return _buildMessageItem(context, item as TextMessageItem);
|
||||
case ChatItemType.toolCall:
|
||||
return _buildToolCallItem(context, item as ToolCallItem);
|
||||
return _buildMessageItem(
|
||||
context,
|
||||
item as TextMessageItem,
|
||||
onSuggestedActionTap: onSuggestedActionTap,
|
||||
);
|
||||
case ChatItemType.toolResult:
|
||||
return _buildToolResultItem(context, item as ToolResultItem);
|
||||
}
|
||||
}
|
||||
|
||||
static Widget _buildMessageItem(BuildContext context, TextMessageItem item) {
|
||||
static Widget _buildMessageItem(
|
||||
BuildContext context,
|
||||
TextMessageItem item, {
|
||||
ValueChanged<String>? onSuggestedActionTap,
|
||||
}) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isUser = item.sender == MessageSender.user;
|
||||
final maxMessageWidth =
|
||||
@@ -41,6 +49,11 @@ class HomeChatItemRenderer {
|
||||
item.attachments,
|
||||
);
|
||||
final hasRenderableAttachments = imageAttachments.isNotEmpty;
|
||||
final suggestedActionTap = onSuggestedActionTap;
|
||||
final shouldRenderSuggestions =
|
||||
!isUser &&
|
||||
item.suggestedActions.isNotEmpty &&
|
||||
suggestedActionTap != null;
|
||||
return Column(
|
||||
crossAxisAlignment: isUser
|
||||
? CrossAxisAlignment.end
|
||||
@@ -98,6 +111,29 @@ class HomeChatItemRenderer {
|
||||
imageAttachments: imageAttachments,
|
||||
),
|
||||
),
|
||||
if (shouldRenderSuggestions)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: AppSpacing.xs),
|
||||
child: Wrap(
|
||||
spacing: AppSpacing.sm,
|
||||
runSpacing: AppSpacing.xs,
|
||||
children: item.suggestedActions
|
||||
.map(
|
||||
(action) => GestureDetector(
|
||||
onTap: () => suggestedActionTap(action),
|
||||
child: Text(
|
||||
action,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: colorScheme.primary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -221,83 +257,6 @@ class HomeChatItemRenderer {
|
||||
);
|
||||
}
|
||||
|
||||
static Widget _buildToolCallItem(BuildContext context, ToolCallItem item) {
|
||||
final l10n = context.l10n;
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final (statusText, statusColor, statusIcon) = switch (item.status) {
|
||||
ToolCallStatus.pending => (
|
||||
l10n.homeToolPreparing,
|
||||
colorScheme.onSurfaceVariant,
|
||||
LucideIcons.clock,
|
||||
),
|
||||
ToolCallStatus.executing => (
|
||||
l10n.homeToolExecuting,
|
||||
colorScheme.primary,
|
||||
LucideIcons.loader,
|
||||
),
|
||||
ToolCallStatus.error => (
|
||||
item.errorMessage ?? l10n.homeToolExecutionFailed,
|
||||
colorScheme.error,
|
||||
LucideIcons.alertCircle,
|
||||
),
|
||||
ToolCallStatus.completed => (
|
||||
l10n.homeToolCompleted,
|
||||
colorScheme.tertiary,
|
||||
LucideIcons.checkCircle,
|
||||
),
|
||||
};
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(AppSpacing.md),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainerLow,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(color: colorScheme.outlineVariant),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 28,
|
||||
height: 28,
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surface,
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
border: Border.all(color: colorScheme.outlineVariant),
|
||||
),
|
||||
child: Icon(statusIcon, size: 14, color: statusColor),
|
||||
),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
localizeToolName(item.toolName),
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.xs),
|
||||
Text(
|
||||
statusText,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: statusColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static Widget _buildToolResultItem(
|
||||
BuildContext context,
|
||||
ToolResultItem item,
|
||||
|
||||
Reference in New Issue
Block a user