Documentation
¶
Overview ¶
Package llmnode implements the Go-native "llm" graph node and exposes a Register helper for binding it into a node.Factory.
The node calls an LLM (resolved through llm.LLMResolver) and routes optional tool calls through a tool.Registry. Streaming events (token / tool_call / tool_result) are emitted via the graph.StreamPublisher handed in on graph.ExecutionContext.Publisher.
Index ¶
- Constants
- func Register(factory *node.Factory, resolver llm.LLMResolver, toolReg *tool.Registry)
- type Config
- type Node
- func (n *Node) Config() map[string]any
- func (n *Node) ExecuteBoard(ctx graph.ExecutionContext, board *graph.Board) error
- func (n *Node) ID() string
- func (n *Node) InputPorts() []graph.Port
- func (n *Node) OutputPorts() []graph.Port
- func (n *Node) SetConfig(c map[string]any)
- func (n *Node) Type() string
Constants ¶
const ( // VarResponse holds the assistant's text response written by terminal LLM nodes. VarResponse = "response" // VarUsage holds the cumulative TokenUsage for the current node execution. VarUsage = "usage" // VarToolPending is true when the LLM round produced tool_calls awaiting // dispatch and false otherwise. VarToolPending = "tool_pending" // VarToolOutput captures the aggregated string output of executed tools. VarToolOutput = "tool_output" // VarPrevMessageCount snapshots how many messages were on the channel // before the LLM node ran, so summarisation/continuation logic can detect // new turns. VarPrevMessageCount = "__prev_message_count" // VarSummaryIndex carries an optional summary string injected into the // system prompt by long-context strategies. VarSummaryIndex = "__summary_index" // VarInternalUsage accumulates TokenUsage across LLM rounds within a single // graph execution. VarInternalUsage = "__usage" )
Board variable keys produced or consumed by the LLM node.
const CancelledToolResultContent = "[cancelled by interrupt]"
CancelledToolResultContent is the canonical body the round driver stamps onto synthetic tool_results when a tool_call could not be dispatched because the round was interrupted. Downstream consumers (memory writers, agent layer) MAY pattern-match on this exact string to recognise a cancelled call without losing the call→result pairing that LLM providers require.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Config ¶
type Config struct {
SystemPrompt string `json:"system_prompt" yaml:"system_prompt"`
Model string `json:"model,omitempty" yaml:"model,omitempty"`
Temperature *float64 `json:"temperature,omitempty" yaml:"temperature,omitempty"`
MaxTokens int64 `json:"max_tokens,omitempty" yaml:"max_tokens,omitempty"`
OutputKey string `json:"output_key,omitempty" yaml:"output_key,omitempty"`
MessagesChannel string `json:"messages_channel,omitempty" yaml:"messages_channel,omitempty"`
JSONMode bool `json:"json_mode,omitempty" yaml:"json_mode,omitempty"`
Thinking bool `json:"thinking,omitempty" yaml:"thinking,omitempty"`
TrackSteps bool `json:"track_steps,omitempty" yaml:"track_steps,omitempty"`
ToolNames []string `json:"tool_names,omitempty" yaml:"tool_names,omitempty"`
}
Config configures an LLM graph node. Fields fall into two groups:
- Graph-level board I/O: SystemPrompt, OutputKey, MessagesChannel, TrackSteps — consumed by Node.ExecuteBoard around the round boundary.
- Pure LLM call parameters: Model, Temperature, MaxTokens, JSONMode, Thinking, ToolNames — forwarded into the in-package round driver via Config.generateOptions.
The split exists to keep the round driver (round.go) ignorant of the graph board, which is essential for testing it in isolation.
MessagesChannel selects the typed-message channel the node reads from and writes to. The empty string (zero value) means graph.MainChannel, shared by every LLM node in the graph. Any other name produces an "isolated" channel; an upstream node (or the caller) is responsible for seeding it with at least one message before the node runs.
func ConfigFromMap ¶
ConfigFromMap parses a Config from a generic map via JSON round-trip.
String values that originate from board template references (e.g. "${board.temperature}") are not valid JSON for non-string fields. The isDeferred predicate (typically variable.ContainsRef) is consulted to decide what to do with such values:
- When isDeferred is nil, an unparseable string returns an error.
- When isDeferred reports true, the entry is dropped so the field receives its zero value at build time and gets re-parsed at execute time once the resolver substitutes the real value.
The input map is never mutated; coercion happens on a shallow clone.
type Node ¶
type Node struct {
// contains filtered or unexported fields
}
Node is a Go-native graph node that calls an LLM, dispatches tool calls, and manages message history on the board.