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 ¶
- func ConvergeChatParent(ctx context.Context, client graphql.Client, c Coords)
- func EnsureChatParent(ctx context.Context, client graphql.Client, c Coords)
- func Mentions(body string) []string
- func NewCmdChat(f *cmdutil.Factory) *cobra.Command
- func ResolveBody(cmd *cobra.Command, body, bodyFile string, stdin io.Reader) (string, error)
- type Coords
- type Message
- type PostInput
- type PostResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ConvergeChatParent ¶ added in v0.9.0
ConvergeChatParent retypes an EXISTING chat structure onto the canonical D-2026-08-07-004 types — the migration path for chats materialized before the shape change, whose messages container was created typed `chat`. Deliberately separate from EnsureChatParent: per-post convergence would tax every message with extra write calls forever, so retyping runs from an explicit, idempotent setup step (`hadron team init`; other chats use `hadron node update <container> --type record`). Best-effort like Ensure — a missing node (nothing posted yet) or a permission refusal is ignored.
func EnsureChatParent ¶ added in v0.9.0
EnsureChatParent best-effort creates the chat's structural nodes so the chat is real and copyable in the portal: the CHAT ENTITY (the parent of the messages container) typed `chat`, and the messages container itself as a plain `record` (D-2026-08-07-004 — the chat type belongs to the entity, not the container; a messagesLoc with no parent gets only the container). Create-only, so a re-post conflicts harmlessly; all outcomes are ignored — this must never affect the post.
func Mentions ¶ added in v0.9.0
mentions extracts the distinct @handles from a body, in first-seen order.
func NewCmdChat ¶
NewCmdChat builds the `chat` command group.
func ResolveBody ¶ added in v0.9.0
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.
Types ¶
type Coords ¶ added in v0.9.0
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"`
}
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
Handle string
Identity string
Role string
Body string
// ReplyTo is the loc (or URN) of the message this answers; adds the
// reply edge inline with the create.
ReplyTo string
// Extra adds additive data fields (e.g. sessionId, #369 D16). Dialect
// keys (author/body/timestamp/identity/role/mentions) always win — an
// Extra entry never overrides them.
Extra map[string]any
}
PostInput is one message for PostMessage — the single implementation of the message-node dialect's write side, shared by `hadron chat post` and `hadron team chat post` so the shape can't drift between them (or from the hadron-client push channel it mirrors).
type PostResult ¶ added in v0.9.0
PostResult is the created message's address.
func PostMessage ¶ added in v0.9.0
PostMessage builds the timestamped colon-safe loc, assembles the message in the CANONICAL chat shape (D-2026-08-07-001/-004: body in `content`, the envelope in `data`, nodeType `chat-message` — the academy data.body dialect is retired on the write side, still accepted on reads), best-effort materializes the chat entity + messages container, and creates the message node (with the optional reply edge) in one round-trip.