Skip to content

feat: add an interactive chat command - #86

Open
ConnorMoss02 wants to merge 9 commits into
a2aproject:mainfrom
ConnorMoss02:feat/34-chat
Open

ConnorMoss02 wants to merge 9 commits into
a2aproject:mainfrom
ConnorMoss02:feat/34-chat

Conversation

@ConnorMoss02

@ConnorMoss02 ConnorMoss02 commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Adds a2a chat. It reads a message, sends it, prints the reply and loops. The context id carries across turns and an input-required task continues with your next message.

--stream works like it does for send, and --context-id and --task-id pick up an existing conversation. Ctrl-C cancels a running turn, and a failed turn prints the error without ending the chat. It stops on auth-required and prints the ids on /quit, EOF or Ctrl-C at the prompt. When stdin or stdout isn't a terminal it sends once and exits.

Fixes #34

@yarolegovich yarolegovich left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the PR! overall looks good, but I'd encourage to polish the overall chat UX further before merging it

Comment thread internal/cli/chat.go Outdated
Short: "Chat with an agent, carrying the conversation across turns",
Long: "Chat with an agent interactively. Each reply continues the same conversation: the context id is carried " +
"across turns, and an input-required task is continued with your next message. Type " + chatQuit + " or press " +
"Ctrl-D to exit; the context and task ids are printed so you can resume with send.\n\n" +

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's wrap the context so that a running turn gets cancelled through ctx ( signal.NotifyContext(cmd.Context(), os.Interrupt)). this will however require moving lines.Scan() blocking call into a background goroutine

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 936c233. Ctrl-C now cancels the running turn and drops you back at the prompt. Ctrl-C at the prompt exits and prints the ids. Input reads on a goroutine so the interrupt gets noticed.

Comment thread internal/cli/chat.go
defer cancel()

result, err := s.client.SendMessage(ctx, &a2a.SendMessageRequest{Message: msg, Tenant: s.cfg.tenant})
if err != nil {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably keep the chat session open on send message errors

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 7d78c4c. A failed turn prints the error like send does and the chat keeps going. Auth-required still ends it.

Comment thread internal/cli/chat.go Outdated
const chatQuit = "/quit"

func newChatCmd(cfg *globalConfig, isTerminal func() bool) *cobra.Command {
return &cobra.Command{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's add support for --context-id and --task-id to allow resuming a task in chat mode

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 2554dae. Same flags and help text as send, and the first message goes out with those ids.

Comment thread internal/cli/chat.go Outdated
ctx, cancel := context.WithTimeout(ctx, s.cfg.timeout)
defer cancel()

result, err := s.client.SendMessage(ctx, &a2a.SendMessageRequest{Message: msg, Tenant: s.cfg.tenant})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we're not in a rush with releasing chat support, so would be nice to have --stream option supported here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in e5288f1. I pulled the streaming code out of send into sendStreaming so both commands use it.

@ConnorMoss02

Copy link
Copy Markdown
Contributor Author

I also took a stab at sending CancelTask when a turn is interrupted (663dd60), so the agent stops working on it too. Happy to roll it back if you'd rather keep that out of this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add interactive chat for multi-turn agent sessions

3 participants