Help us shape the future of Go! Take the 2026 Go Developer Survey

chat

package
v0.21.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package chat implements `hadron chat ...` — a token-lean surface for AI agents (and humans) participating in a Hadron team-chat memory (see the how-to guide "Set up an agent team chat"). Messages are message-type nodes under a `messagesLoc` prefix, in the CANONICAL chat shape (body in `content`, the envelope in `data` — D-2026-08-07-004); the server assigns an ordering `seq`. `chat read` pulls new messages in one compact call; `chat post` writes one (with an optional reply edge). Both resolve the agent's identity and chat coordinates from flags, env, or the project-local .hadron/config.json shared with the hadron-client push channel.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Mentions added in v0.9.0

func Mentions(body string) []string

mentions extracts the distinct @handles from a body, in first-seen order.

func NewCmdChat

func NewCmdChat(f *cmdutil.Factory) *cobra.Command

NewCmdChat builds the `chat` command group.

func RefuseBodyStdinFromTerminal added in v0.15.0

func RefuseBodyStdinFromTerminal(stdinIsTerminal bool) error

RefuseBodyStdinFromTerminal is ResolveBody's terminal refusal on its own, so a caller that does network work before reading the body can fail first. The label fits both spellings of the source, `--body -` and a positional -.

func ResolveBody added in v0.9.0

func ResolveBody(cmd *cobra.Command, body, bodyFile string, stdin io.Reader, stdinIsTerminal bool) (string, error)

ResolveBody returns the message text from exactly one source: --body-file (a file), --body - (stdin), or --body <text> (inline). The mutually-exclusive / one-required flag group is enforced by cobra; this reads whichever was set.

A message body is a DOCUMENT (#648): "-" from an interactive terminal is refused, since the line discipline can truncate it before it is read.

Types

type Coords added in v0.9.0

type Coords struct {
	Memory      string
	MessagesLoc string
}

Coords is the resolved (memory, messagesLoc) of one chat. messagesLoc is the loc prefix whose direct child nodes are the messages (e.g. "team-chat:academy:chat:messages").

type Message added in v0.9.0

type Message struct {
	Seq       *int   `json:"seq"`
	Loc       string `json:"loc"`
	Author    string `json:"author"`
	Identity  string `json:"identity,omitempty"`
	Role      string `json:"role,omitempty"`
	Timestamp string `json:"timestamp,omitempty"`
	Body      string `json:"body"`
	// SessionID attributes an agent-posted message to the coding session
	// driving the persona (#369 D16) — the driver is Session.userId. Absent
	// on human/channel posts; additive, the push channel ignores it.
	SessionID string `json:"sessionId,omitempty"`
	// Mentions as stored by the poster; readers needing them should fall
	// back to Mentions(Body) when empty (hand-created messages omit them).
	Mentions []string `json:"mentions,omitempty"`
	// The platform envelope's identity fields (#630). createChannelMessage
	// writes these and this reader dropped all three, so `--json` could not
	// tell a WORKER post from a human one — the distinction the Worker model
	// exists to record. Absent on the retired academy rows, hence omitempty.
	AuthorWorkerID string `json:"authorWorkerId,omitempty"`
	AuthorUserID   string `json:"authorUserId,omitempty"`
	AuthorAppID    string `json:"authorAppId,omitempty"`
}

Message is the parsed, chat-shaped view of one message node — only the fields a participant cares about, lifted out of the node's generic `data` block.

func CollectMessages added in v0.9.0

func CollectMessages(ctx context.Context, client graphql.Client, c Coords, since int) ([]Message, error)

CollectMessages drains every message node under the chat prefix (findNodes caps a page, so it pages to exhaustion — #23), keeps those with seq > since, and returns them in seq order. The read side of the shared message-node dialect (see PostMessage).

type PostInput added in v0.9.0

type PostInput struct {
	Coords Coords
	Body   string
	// ReplyTo is the seq, or the loc/URN, of the message this answers.
	ReplyTo string
	// Session binds the post to a worker session, which is what makes it the
	// WORKER speaking rather than the human. It is what replaced the identity
	// envelope: the server derives authorship from it.
	Session string
}

PostInput is one message for PostMessage.

The pre-Channel identity envelope (Handle/Identity/Role) and the additive Extra bag are GONE from this type rather than kept as ignored fields: a struct field that is assigned and never read is indistinguishable from one that works. The flags themselves survive at the command layer, where warnDeprecatedIdentityFlags answers for them.

type PostResult added in v0.9.0

type PostResult struct {
	// NodeID is the message node. The client no longer knows the loc — the
	// server mints it — so this is the address a caller gets back.
	NodeID string
	Seq    *int
	// Author is the name the SERVER recorded. Echoed back rather than assumed,
	// because posting under the wrong identity is the one mistake this surface
	// can make silently.
	Author *string
}

PostResult is the created message's address, as the SERVER minted it.

func PostMessage added in v0.9.0

func PostMessage(ctx context.Context, client graphql.Client, in PostInput) (PostResult, error)

PostMessage posts one message through the Channel this chat IS (createChannelMessage), creating that Channel on first post.

It writes NO node structure of its own. That is the point of #367: the client used to mint the loc, assemble the `data` envelope, parse @mentions and best-effort materialize two container nodes, which made it a second, structurally incompatible chat model beside the server's. The server now owns all of it — including the loc's random component and the atomic seq, which is why this change fixes #367's two live bugs without either being patched here.

The read path is deliberately NOT moved (docs/plans/chat-as-channel-wrapper.md §6): it already reads these same nodes, and a read regression must not be able to hide inside a write change.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL