mirror of
https://github.com/davidkaya/aryx.git
synced 2026-11-15 06:42:04 +01:00
feat: add ask_user interactive user input to frontend
Wire the sidecar user-input-requested protocol event through the main process, IPC layer, and renderer UI so agents can ask the user interactive questions with choices and freeform input. - Add UserInputRequestedEvent and ResolveUserInputCommand to sidecar protocol types - Add resolveUserInput method to SidecarClient and onUserInput callback to runTurn - Create PendingUserInputRecord domain type and add pendingUserInput to SessionRecord - Add handleUserInputRequested and resolveSessionUserInput to AryxAppService with handle management - Register sessions:resolve-user-input IPC channel with preload bridge - Create UserInputBanner component with choice buttons and freeform input - Integrate UserInputBanner into ChatPane with header indicator Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
1 parent
2ae4bd01b4
commit
f15b1aedb1
14 files changed
+356
-12
No files matched your search
@@ -26,6 +26,7 @@ export const ipcChannels = {
|
||||
sendSessionMessage: 'sessions:send-message',
|
||||
cancelSessionTurn: 'sessions:cancel-turn',
|
||||
resolveSessionApproval: 'sessions:resolve-approval',
|
||||
resolveSessionUserInput: 'sessions:resolve-user-input',
|
||||
querySessions: 'sessions:query',
|
||||
updateSessionModelConfig: 'sessions:update-model-config',
|
||||
selectProject: 'selection:project',
|
||||
|
||||
@@ -36,6 +36,13 @@ export interface ResolveSessionApprovalInput {
|
||||
decision: ApprovalDecision;
|
||||
}
|
||||
|
||||
export interface ResolveSessionUserInputInput {
|
||||
sessionId: string;
|
||||
userInputId: string;
|
||||
answer: string;
|
||||
wasFreeform: boolean;
|
||||
}
|
||||
|
||||
export interface UpdateSessionModelConfigInput {
|
||||
sessionId: string;
|
||||
model: string;
|
||||
@@ -126,6 +133,7 @@ export interface ElectronApi {
|
||||
sendSessionMessage(input: SendSessionMessageInput): Promise<void>;
|
||||
cancelSessionTurn(input: CancelSessionTurnInput): Promise<void>;
|
||||
resolveSessionApproval(input: ResolveSessionApprovalInput): Promise<WorkspaceState>;
|
||||
resolveSessionUserInput(input: ResolveSessionUserInputInput): Promise<WorkspaceState>;
|
||||
updateSessionModelConfig(input: UpdateSessionModelConfigInput): Promise<WorkspaceState>;
|
||||
querySessions(input: QuerySessionsInput): Promise<SessionQueryResult[]>;
|
||||
selectProject(projectId?: string): Promise<WorkspaceState>;
|
||||
|
||||
@@ -92,12 +92,21 @@ export interface ResolveApprovalCommand {
|
||||
decision: ApprovalDecision;
|
||||
}
|
||||
|
||||
export interface ResolveUserInputCommand {
|
||||
type: 'resolve-user-input';
|
||||
requestId: string;
|
||||
userInputId: string;
|
||||
answer: string;
|
||||
wasFreeform: boolean;
|
||||
}
|
||||
|
||||
export type SidecarCommand =
|
||||
| DescribeCapabilitiesCommand
|
||||
| ValidatePatternCommand
|
||||
| RunTurnCommand
|
||||
| CancelTurnCommand
|
||||
| ResolveApprovalCommand;
|
||||
| ResolveApprovalCommand
|
||||
| ResolveUserInputCommand;
|
||||
|
||||
export interface RunTurnLocalMcpServerConfig {
|
||||
id: string;
|
||||
@@ -220,6 +229,18 @@ export interface ApprovalRequestedEvent {
|
||||
permissionDetail?: PermissionDetail;
|
||||
}
|
||||
|
||||
export interface UserInputRequestedEvent {
|
||||
type: 'user-input-requested';
|
||||
requestId: string;
|
||||
sessionId: string;
|
||||
userInputId: string;
|
||||
agentId?: string;
|
||||
agentName?: string;
|
||||
question: string;
|
||||
choices?: string[];
|
||||
allowFreeform?: boolean;
|
||||
}
|
||||
|
||||
export interface CommandErrorEvent {
|
||||
type: 'command-error';
|
||||
requestId: string;
|
||||
@@ -238,5 +259,6 @@ export type SidecarEvent =
|
||||
| TurnCompleteEvent
|
||||
| AgentActivityEvent
|
||||
| ApprovalRequestedEvent
|
||||
| UserInputRequestedEvent
|
||||
| CommandErrorEvent
|
||||
| CommandCompleteEvent;
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
type SessionApprovalSettings,
|
||||
} from '@shared/domain/approval';
|
||||
import type { SessionRunRecord } from '@shared/domain/runTimeline';
|
||||
import type { PendingUserInputRecord } from '@shared/domain/userInput';
|
||||
|
||||
export type ChatRole = 'system' | 'user' | 'assistant';
|
||||
export type SessionStatus = 'idle' | 'running' | 'error';
|
||||
@@ -48,6 +49,7 @@ export interface SessionRecord {
|
||||
approvalSettings?: SessionApprovalSettings;
|
||||
pendingApproval?: PendingApprovalRecord;
|
||||
pendingApprovalQueue?: PendingApprovalRecord[];
|
||||
pendingUserInput?: PendingUserInputRecord;
|
||||
runs: SessionRunRecord[];
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
export type UserInputStatus = 'pending' | 'answered';
|
||||
|
||||
export interface PendingUserInputRecord {
|
||||
id: string;
|
||||
status: UserInputStatus;
|
||||
agentId?: string;
|
||||
agentName?: string;
|
||||
question: string;
|
||||
choices?: string[];
|
||||
allowFreeform: boolean;
|
||||
requestedAt: string;
|
||||
answer?: string;
|
||||
answeredAt?: string;
|
||||
}
|
||||
Reference in new issue
Block a user