feat: add conversation management, persistence, and mobile app spec
Major enhancements to voice assistant with conversation persistence and mobile app planning: - Add conversation management with multiple active conversations - Implement conversation persistence (save/load from disk) - Add conversation selector UI for switching between conversations - Enhance agent prompt with per-conversation tmux sessions - Add mobile app technical specification (React Native + Expo) - Improve UI with active processes view and agent stream - Add ACP (Agent Control Protocol) server implementation Mobile spec details: - React Native with Expo SDK 54+ - NativeWind v5 for styling - Share Zod schemas/types from server - Android in-call experience (InCallManager) - Direct WebSocket connection via Tailscale - Same audio quality as web prototype 🤖 Generated with [Claude Code](https://claude.com/claude-code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
co-authored by
Claude
Happy
parent
37a363da6d
commit
4f2c2fc14a
@@ -25,11 +25,17 @@ export const AudioPlayedMessageSchema = z.object({
|
||||
id: z.string(),
|
||||
});
|
||||
|
||||
export const LoadConversationRequestMessageSchema = z.object({
|
||||
type: z.literal("load_conversation_request"),
|
||||
conversationId: z.string(),
|
||||
});
|
||||
|
||||
export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
|
||||
UserTextMessageSchema,
|
||||
AudioChunkMessageSchema,
|
||||
AbortRequestMessageSchema,
|
||||
AudioPlayedMessageSchema,
|
||||
LoadConversationRequestMessageSchema,
|
||||
]);
|
||||
|
||||
export type SessionInboundMessage = z.infer<typeof SessionInboundMessageSchema>;
|
||||
@@ -103,6 +109,48 @@ export const ArtifactMessageSchema = z.object({
|
||||
}),
|
||||
});
|
||||
|
||||
export const ConversationLoadedMessageSchema = z.object({
|
||||
type: z.literal("conversation_loaded"),
|
||||
payload: z.object({
|
||||
conversationId: z.string(),
|
||||
messageCount: z.number(),
|
||||
}),
|
||||
});
|
||||
|
||||
export const AgentCreatedMessageSchema = z.object({
|
||||
type: z.literal("agent_created"),
|
||||
payload: z.object({
|
||||
agentId: z.string(),
|
||||
status: z.string(),
|
||||
type: z.literal("claude"),
|
||||
}),
|
||||
});
|
||||
|
||||
export const AgentUpdateMessageSchema = z.object({
|
||||
type: z.literal("agent_update"),
|
||||
payload: z.object({
|
||||
agentId: z.string(),
|
||||
timestamp: z.date(),
|
||||
notification: z.any(), // SessionNotification from ACP - complex type, using any for simplicity
|
||||
}),
|
||||
});
|
||||
|
||||
export const AgentStatusMessageSchema = z.object({
|
||||
type: z.literal("agent_status"),
|
||||
payload: z.object({
|
||||
agentId: z.string(),
|
||||
status: z.string(),
|
||||
info: z.object({
|
||||
id: z.string(),
|
||||
status: z.string(),
|
||||
createdAt: z.date(),
|
||||
type: z.literal("claude"),
|
||||
sessionId: z.string().optional(),
|
||||
error: z.string().optional(),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [
|
||||
ActivityLogMessageSchema,
|
||||
AssistantChunkMessageSchema,
|
||||
@@ -110,6 +158,10 @@ export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [
|
||||
TranscriptionResultMessageSchema,
|
||||
StatusMessageSchema,
|
||||
ArtifactMessageSchema,
|
||||
ConversationLoadedMessageSchema,
|
||||
AgentCreatedMessageSchema,
|
||||
AgentUpdateMessageSchema,
|
||||
AgentStatusMessageSchema,
|
||||
]);
|
||||
|
||||
export type SessionOutboundMessage = z.infer<
|
||||
@@ -123,6 +175,10 @@ export type AudioOutputMessage = z.infer<typeof AudioOutputMessageSchema>;
|
||||
export type TranscriptionResultMessage = z.infer<typeof TranscriptionResultMessageSchema>;
|
||||
export type StatusMessage = z.infer<typeof StatusMessageSchema>;
|
||||
export type ArtifactMessage = z.infer<typeof ArtifactMessageSchema>;
|
||||
export type ConversationLoadedMessage = z.infer<typeof ConversationLoadedMessageSchema>;
|
||||
export type AgentCreatedMessage = z.infer<typeof AgentCreatedMessageSchema>;
|
||||
export type AgentUpdateMessage = z.infer<typeof AgentUpdateMessageSchema>;
|
||||
export type AgentStatusMessage = z.infer<typeof AgentStatusMessageSchema>;
|
||||
|
||||
// Type exports for payload types
|
||||
export type ActivityLogPayload = z.infer<typeof ActivityLogPayloadSchema>;
|
||||
|
||||
Reference in New Issue
Block a user