Documentation
¶
Overview ¶
Package pathwalk executes conversational pathway JSON files as agentic pipelines. A pathway is a directed graph of nodes connected by edges. The Engine walks the graph step-by-step: NodeTypeLLM nodes invoke an LLM, NodeTypeRoute nodes evaluate conditions, NodeTypeWebhook nodes make HTTP calls, and NodeTypeTerminal nodes terminate the run.
Quick start:
pathway, err := pathwalk.ParsePathway("my_pathway.json")
llm := pathwalk.NewOpenAIClient(apiKey, "", "gpt-4o")
engine := pathwalk.NewEngine(pathway, llm)
result, err := engine.Run(ctx, "your task description")
Index ¶
- Constants
- func CallPurposeFromContext(ctx context.Context) string
- func NodeIDFromContext(ctx context.Context) string
- func WithCallPurpose(ctx context.Context, purpose string) context.Context
- func WithNodeID(ctx context.Context, nodeID string) context.Context
- type CompletionRequest
- type CompletionResponse
- type Edge
- type Engine
- type EngineOption
- type LLMClient
- type LogEntry
- type Message
- type Node
- type NodeTool
- type NodeType
- type OpenAIClient
- type Pathway
- type RouteCondition
- type RouteRule
- type RunResult
- type State
- type Step
- type StepResult
- type Tool
- type ToolCall
- type ToolResponsePathway
- type ValidationError
- type ValidationResult
- type VariableDef
Constants ¶
const ( // NodeIDContextKey is set in the context before each LLM call so mocks // can inspect which node triggered the call. NodeIDContextKey contextKey = "nodeID" // CallPurposeContextKey distinguishes the purpose of an LLM call. // Values: "execute", "extract_vars", "route", "check_global" CallPurposeContextKey contextKey = "callPurpose" )
const GlobalCheckNodeID = "$global_check"
GlobalCheckNodeID is the node ID placed in context during the global-node-check LLM call each step. Use it with MockLLMClient.OnNodePurpose in tests:
mock.OnNodePurpose(pathwalk.GlobalCheckNodeID, "check_global", ...)
Variables ¶
This section is empty.
Functions ¶
func CallPurposeFromContext ¶
CallPurposeFromContext retrieves the call purpose from the context.
func NodeIDFromContext ¶
NodeIDFromContext retrieves the node ID from the context.
func WithCallPurpose ¶
WithCallPurpose returns a context carrying the call purpose.
Types ¶
type CompletionRequest ¶
type CompletionRequest struct {
Model string
Messages []Message
Tools []Tool
Temperature float64
MaxTokens int
}
CompletionRequest is the input to LLMClient.Complete.
type CompletionResponse ¶
CompletionResponse is the output from LLMClient.Complete.
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine executes a parsed pathway using an LLM and optional tools.
func NewEngine ¶
func NewEngine(pathway *Pathway, llm LLMClient, opts ...EngineOption) *Engine
NewEngine creates an Engine for the given pathway and LLM client. Panics if pathway or llm is nil.
func (*Engine) Run ¶
Run executes the pathway with `task` as the initial context.
Unlike Step, Run can return both a non-nil *RunResult and a non-nil error simultaneously when Reason is "error" or "missing_node". Callers should always inspect both: the result contains the partial execution state (steps taken, variables extracted so far) and the error describes what went wrong.
func (*Engine) Step ¶
Step executes a single node in the pathway and returns the result. State is mutated in place (variables merged, step appended). Call this repeatedly with the returned NextNodeID until StepResult.Done is true.
Example:
state := NewState("my task")
for {
result, err := engine.Step(ctx, state, startNodeID)
if err != nil || result.Done {
break
}
nodeID = result.NextNodeID
}
type EngineOption ¶
type EngineOption func(*Engine)
EngineOption is a functional option for Engine.
func WithGlobalNodeCheck ¶
func WithGlobalNodeCheck(enabled bool) EngineOption
WithGlobalNodeCheck enables or disables the per-step global node interception. By default it is enabled whenever the pathway has at least one global node.
func WithLogger ¶
func WithLogger(log *slog.Logger) EngineOption
WithLogger sets the logger for the engine. If not set, slog.Default() is used.
func WithMaxSteps ¶
func WithMaxSteps(n int) EngineOption
WithMaxSteps sets the maximum number of nodes to visit.
func WithTools ¶
func WithTools(tools ...Tool) EngineOption
WithTools adds tools to the engine's tool registry.
type LLMClient ¶
type LLMClient interface {
// Complete sends messages to the LLM, executes any tool calls, and returns
// the final text content plus a record of all tool calls made.
Complete(ctx context.Context, req CompletionRequest) (*CompletionResponse, error)
}
LLMClient is the interface for making LLM completions. The implementation is responsible for handling the tool-call loop.
type LogEntry ¶
type LogEntry struct {
Time time.Time `json:"time"`
Level string `json:"level"`
Message string `json:"message"`
Attrs map[string]any `json:"attrs,omitempty"`
}
LogEntry is a single captured log record, safe for serialisation.
type Node ¶
type Node struct {
ID string
Type NodeType
Name string
IsStart bool
IsGlobal bool
GlobalLabel string
// LLM node
Prompt string
Text string
Condition string
ExtractVars []VariableDef
Temperature float64
// Terminal node
TerminalText string
// Webhook node
WebhookURL string
WebhookMethod string
WebhookHeaders map[string]string
WebhookBody any
// Node-level tools (parsed from JSON, scoped to this node only)
Tools []NodeTool
// Route node
Routes []RouteRule
FallbackNodeID string
// MaxVisits caps how many times this node may be visited in a single run.
// 0 means use the pathway-level MaxVisitsPerNode default (or no limit).
MaxVisits int
}
Node is a parsed node from the pathway.
type NodeTool ¶
type NodeTool struct {
Name string
Description string
Type string // "webhook" or "custom_tool"
Behavior string // "feed_context" — response fed back into conversation
// Webhook config
URL string
Method string
Headers map[string]string
Body string // raw body template with {{variable}} placeholders
// Timeout in seconds for the HTTP request. 0 means use the default (30s).
Timeout int
// Retries is the number of retry attempts on failure. 0 means no retries.
Retries int
// Speech is optional text the agent speaks while the tool executes
// (relevant for voice agents; ignored by the default engine).
Speech string
// Variables to extract from the tool's response
ExtractVars []VariableDef
// ResponsePathways defines conditional routing based on the tool's response.
// When Behavior is "feed_context", the LLM sees the result and continues.
// When pathways have conditions, a matching pathway can redirect the
// conversation to a different node, overriding normal edge-based routing.
ResponsePathways []ToolResponsePathway
}
NodeTool is a declarative tool definition attached to a specific node in the pathway JSON. Unlike Tool, it carries no Go function — the engine constructs an executable Tool from the config at runtime (e.g. performing a webhook call).
type NodeType ¶
type NodeType string
NodeType identifies the kind of node in a pathway.
const ( // NodeTypeLLM invokes the LLM to execute the node's prompt and optionally // extracts variables from the response. NodeTypeLLM NodeType = "llm" // NodeTypeTerminal terminates the pathway run and returns the node's TerminalText. NodeTypeTerminal NodeType = "terminal" // NodeTypeWebhook performs an HTTP request and optionally extracts variables // from the JSON response. NodeTypeWebhook NodeType = "webhook" // NodeTypeRoute evaluates conditions against the current state variables to // pick the next node without calling the LLM. NodeTypeRoute NodeType = "route" )
type OpenAIClient ¶
type OpenAIClient struct {
// contains filtered or unexported fields
}
OpenAIClient implements LLMClient using the openai-go SDK. It is compatible with any OpenAI-compatible API (venu, Groq, Ollama, OpenRouter, etc.).
func NewOpenAIClient ¶
func NewOpenAIClient(apiKey, baseURL, model string) *OpenAIClient
NewOpenAIClient creates a new OpenAIClient. apiKey and baseURL can be empty to use environment defaults.
func (*OpenAIClient) Complete ¶
func (c *OpenAIClient) Complete(ctx context.Context, req CompletionRequest) (*CompletionResponse, error)
Complete sends the request to the OpenAI API, handles tool call loops, and returns the final assistant content.
type Pathway ¶
type Pathway struct {
Nodes []*Node
Edges []*Edge
NodeByID map[string]*Node
EdgesFrom map[string][]*Edge // source nodeID → outgoing edges
StartNode *Node
GlobalNodes []*Node // nodes with IsGlobal == true and a non-empty GlobalLabel
GraphQLEndpoint string // optional single GraphQL endpoint (unnamed tools)
GraphQLEndpoints map[string]string // named endpoints → tools get _<name> suffix
// MaxTurns caps the total number of node-to-node transitions in a run.
// 0 means use the engine's WithMaxSteps value (default 50).
MaxTurns int
// MaxVisitsPerNode is the default per-node visit cap for all nodes in the pathway.
// 0 means no limit unless a node's own MaxVisits overrides it.
MaxVisitsPerNode int
}
Pathway holds parsed nodes and edges with lookup indexes.
func ParsePathway ¶
ParsePathway reads a pathway JSON file and returns a Pathway.
func ParsePathwayBytes ¶
ParsePathwayBytes parses a pathway from raw JSON bytes.
type RouteCondition ¶
type RouteCondition struct {
Field string
Operator string // "is", "is not", "contains", "not contains", ">", "<", ">=", "<="
Value string
}
RouteCondition is a single field/operator/value check.
type RouteRule ¶
type RouteRule struct {
Conditions []RouteCondition
TargetID string
}
RouteRule maps a set of conditions (AND-logic) to a target node.
type RunResult ¶
type RunResult struct {
// Output is the last meaningful content produced by the run — the output
// of the last LLM or webhook step that executed before the terminal node.
// Terminal nodes do not contribute to Output.
Output string
Variables map[string]any
Steps []Step
// Reason explains why the run ended. Values: "terminal", "max_steps",
// "error", "dead_end", "missing_node", "max_node_visits".
Reason string
// FailedNode is the name of the node that caused the run to stop when
// Reason is "error" or "max_node_visits". Empty otherwise.
FailedNode string
// Logs contains all log records emitted during this run.
Logs []LogEntry
}
RunResult is the final result of running a pathway.
type State ¶
type State struct {
Task string
Variables map[string]any
Steps []Step
VisitCounts map[string]int // nodeID → number of times visited this run
}
State holds the mutable runtime state of a pathway execution.
func NewState ¶
NewState creates a new execution state for the given task. Use this to initialize state for calls to Engine.Step.
func (*State) StepsSummary ¶
StepsSummary returns a concise summary of the steps taken so far.
func (*State) VarsSummary ¶
VarsSummary returns a human-readable summary of the current variables.
type Step ¶
type Step struct {
NodeID string
NodeName string
Output string
Vars map[string]any
// ToolCalls holds every tool invocation made by the LLM during this node's
// execution. Empty for Route and Terminal nodes.
ToolCalls []ToolCall
// RouteReason is the human-readable explanation for why the engine
// chose the next node (e.g. "single edge", "selected route 2").
RouteReason string
NextNode string
}
Step records what happened at a single node.
type StepResult ¶
type StepResult struct {
Step Step // The step record for this execution
NextNodeID string // Empty when Done=true (terminal, dead_end, error, or max_node_visits)
Done bool // True when the run should terminate
Reason string // "terminal", "dead_end", "error", "missing_node", "max_node_visits"
Output string // Text output from the node
Error string // Error message if Reason=="error" or "max_node_visits"
FailedNode string // Name of the node that caused the stop when Reason is "error" or "max_node_visits"
Logs []LogEntry // Log records emitted during this step
}
StepResult captures what happened during a single node execution.
type Tool ¶
type Tool struct {
Name string
Description string
Parameters map[string]any // JSON schema
Fn func(ctx context.Context, args map[string]any) (any, error)
}
Tool is a callable function exposed to the LLM.
type ToolResponsePathway ¶
type ToolResponsePathway struct {
// Type is the trigger type: "default" (always matches)
// or "BlandStatusCode" (matches on HTTP status code).
Type string `json:"type"`
// Condition operator: "==", "!=", ">", "<", ">=", "<=", "contains", "!contains", "is".
// Empty means no condition (always matches).
Operator string `json:"operator,omitempty"`
// Value to compare against (e.g. "200", "error").
Value string `json:"value,omitempty"`
// NodeID is the target node to route to when the condition matches.
NodeID string `json:"nodeId"`
// Name is a human-readable label for this pathway.
Name string `json:"name,omitempty"`
}
ToolResponsePathway describes how to handle a tool's response. It can act as a conditional offramp: if the response matches the condition, route to the specified node instead of continuing normal flow.
type ValidationError ¶
type ValidationError struct {
Field string // JSON path to the failing field
Message string // Human-readable description
}
ValidationError is a single JSON schema violation.
func (ValidationError) Error ¶
func (e ValidationError) Error() string
type ValidationResult ¶
type ValidationResult struct {
SchemaErrors []ValidationError // JSON schema violations
ParseError error // Structural error from ParsePathwayBytes
}
ValidationResult holds the outcome of a schema + parse validation.
func ValidatePathwayBytes ¶
func ValidatePathwayBytes(data []byte) *ValidationResult
ValidatePathwayBytes validates pathway JSON against the bundled JSON schema and then attempts to parse it. Both checks run independently so all errors are visible in a single call.
func (*ValidationResult) Errors ¶
func (r *ValidationResult) Errors() []error
Errors returns all errors as a flat slice, schema errors first then parse error.
func (*ValidationResult) Valid ¶
func (r *ValidationResult) Valid() bool
Valid returns true when there are no schema errors and no parse error.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
pathwalk
command
|
|
|
pathwalk-ui
command
|
|
|
pathwalk-worker
command
|
|
|
Package evals provides a lightweight evaluation framework for pathwalk pathways.
|
Package evals provides a lightweight evaluation framework for pathwalk pathways. |
|
Package pathwaytest provides test helpers for the pathwalk library, including a mock LLM client for unit testing without hitting a real API.
|
Package pathwaytest provides test helpers for the pathwalk library, including a mock LLM client for unit testing without hitting a real API. |
|
Package tools provides built-in tool implementations for use with the pathwalk pathwalk.Engine.
|
Package tools provides built-in tool implementations for use with the pathwalk pathwalk.Engine. |