feat(a2ui): Implement A2UI backend with question handling and WebSocket support

- Added A2UITypes for defining question structures and answers.
- Created A2UIWebSocketHandler for managing WebSocket connections and message handling.
- Developed ask-question tool for interactive user questions via A2UI.
- Introduced platformUtils for platform detection and shell command handling.
- Centralized TypeScript types in index.ts for better organization.
- Implemented compatibility checks for hook templates based on platform requirements.
This commit is contained in:
catlog22
2026-01-31 15:27:12 +08:00
parent 4e009bb03a
commit 715ef12c92
163 changed files with 19495 additions and 715 deletions

View File

@@ -0,0 +1,55 @@
// ========================================
// A2UI TextField Component Renderer
// ========================================
// Maps A2UI TextField component to shadcn/ui Input
import React, { useState, useCallback } from 'react';
import { Input } from '@/components/ui/Input';
import type { ComponentRenderer } from '../../core/A2UIComponentRegistry';
import { resolveLiteralOrBinding } from '../A2UIRenderer';
import type { TextFieldComponent } from '../../core/A2UITypes';
interface A2UITextFieldProps {
component: TextFieldComponent;
state: Record<string, unknown>;
onAction: (actionId: string, params: Record<string, unknown>) => void | Promise<void>;
resolveBinding: (binding: { path: string }) => unknown;
}
/**
* A2UI TextField Component Renderer
* Two-way binding via onChange updates to local state
*/
export const A2UITextField: ComponentRenderer = ({ component, state, onAction, resolveBinding }) => {
const fieldComp = component as TextFieldComponent;
const { TextField: fieldConfig } = fieldComp;
// Resolve initial value from binding or use empty string
const initialValue = fieldConfig.value
? String(resolveLiteralOrBinding(fieldConfig.value, resolveBinding) ?? '')
: '';
// Local state for controlled input
const [localValue, setLocalValue] = useState(initialValue);
// Handle change with two-way binding
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = e.target.value;
setLocalValue(newValue);
// Trigger action with new value
onAction(fieldConfig.onChange.actionId, {
value: newValue,
...(fieldConfig.onChange.parameters || {}),
});
}, [fieldConfig.onChange, onAction]);
return (
<Input
type={fieldConfig.type || 'text'}
value={localValue}
onChange={handleChange}
placeholder={fieldConfig.placeholder}
/>
);
};