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

flowengine

package
v0.2.3 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: AGPL-3.0 Imports: 12 Imported by: 0

Documentation

Index

Constants

View Source
const CompactDefaultModel = "default"

CompactDefaultModel is the sentinel that means "use the server's COMPACT_MODEL env var, resolved at execute time".

View Source
const CompactDefaultThresholdWords = 200
View Source
const QuestionMaxIterations = 10
View Source
const SubflowMaxDepth = 5

Variables

This section is empty.

Functions

func FindOutputInputs

func FindOutputInputs(def FlowDefinition) map[string]bool

func TopologicalSortWithBackEdges

func TopologicalSortWithBackEdges(
	def FlowDefinition,
) ([]string, map[string]bool, error)

func Validate

func Validate(def FlowDefinition) error

Types

type Answer

type Answer struct {
	ID    string `json:"id"`
	Label string `json:"label"`
}

Answer is one branch of a question node. ID is the stable output-handle id (edges reference it); Label is the user-editable display text the classifier matches against. Keeping them separate lets the user rename a branch without detaching its edges.

type Candidate

type Candidate struct {
	NodeID   string `json:"node_id"`
	NodeType string `json:"node_type"`
	Content  string `json:"content"`
}

Candidate is one answer produced by a direct source of user_output. When more than one exists the frontend renders tabs.

type CompactData

type CompactData struct {
	Model          string `json:"model"`
	Prompt         string `json:"prompt"`
	ThresholdWords int    `json:"threshold_words"`
}

type Document

type Document struct {
	Filename string
	Content  string
}

Document is the engine-facing shape of an uploaded file. Loaded by the handler before Execute() and consumed by the files node.

type ExecuteConfig

type ExecuteConfig struct {
	LLM                LLMClient
	BraveAPIKey        string
	CompactModel       string
	Messages           []Message
	Documents          []Document
	OnLLMCost          func(cost float64) error
	OnSearchCharged    func(ctx context.Context, endpoint string, resultCount int)
	OnCompactInflation func(
		ctx context.Context,
		model string,
		originalWords, compactedWords int,
	)
	LoadFlow   func(flowID string) (FlowDefinition, error)
	RootFlowID string
	Streaming  bool
	// contains filtered or unexported fields
}

func (ExecuteConfig) AvailableTools

func (c ExecuteConfig) AvailableTools() []llmclient.ToolDef

AvailableTools returns the tool definitions registered so far this execution, to pass into the model request.

func (ExecuteConfig) ExecuteTool

func (c ExecuteConfig) ExecuteTool(
	ctx context.Context, name, args string,
) (string, error)

ExecuteTool runs a model-requested tool by name.

func (ExecuteConfig) RegisterTool

func (c ExecuteConfig) RegisterTool(
	def llmclient.ToolDef, exec toolExec,
)

RegisterTool makes a tool available to the LLM node that runs after the registering node. Called by tool-provider nodes (e.g. web_search) during their execution.

type ExecuteResult

type ExecuteResult struct {
	// TotalCost is the billed cost (raw groq × markup) for
	// the entire execution. Sourced from cfg.LLM at the
	// end of Execute since all per-call accounting lives
	// in the billedllm Recorder.
	TotalCost   float64
	FinalOutput string
	Candidates  []Candidate
}

func Execute

func Execute(
	ctx context.Context,
	def FlowDefinition,
	userInput string,
	cfg ExecuteConfig,
	emit func(StreamEvent),
) (*ExecuteResult, error)

type Executor

type Executor func(
	ctx context.Context, n NodeCtx,
) (NodeResult, error)

Executor runs a single node and returns its result.

type FilesData

type FilesData struct{}

type FlowDefinition

type FlowDefinition struct {
	Nodes []FlowNode `json:"nodes"`
	Edges []FlowEdge `json:"edges"`
}

type FlowEdge

type FlowEdge struct {
	ID           string `json:"id"`
	Source       string `json:"source"`
	Target       string `json:"target"`
	SourceHandle string `json:"sourceHandle,omitempty"`
}

type FlowNode

type FlowNode struct {
	ID       string          `json:"id"`
	Type     NodeType        `json:"type"`
	Position Position        `json:"position"`
	Data     json.RawMessage `json:"data"`
}

type LLMClient

type LLMClient interface {
	Complete(
		ctx context.Context,
		model string,
		messages []llmclient.Message,
		maxTokens int,
	) (string, error)

	CompleteRaw(
		ctx context.Context,
		model string,
		messages []llmclient.Message,
		tools []llmclient.ToolDef,
		maxTokens int,
	) (llmclient.Message, error)

	Stream(
		ctx context.Context,
		model string,
		messages []llmclient.Message,
		maxTokens int,
	) (<-chan string, <-chan error)

	TotalBilled() float64
}

LLMClient is the interface flow nodes use for all LLM calls. The concrete impl lives in billedllm and records a token_events row for each call. Defining the interface here keeps flowengine free of a billing/DB dependency and makes the nodes trivially mockable.

type LLMData

type LLMData struct {
	Model       string  `json:"model"`
	MaxTokens   int     `json:"max_tokens"`
	Temperature float64 `json:"temperature"`
}

type Message

type Message struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

Message is the canonical role-tagged unit flowing between nodes, and also the type the handler uses to pre-load conversation history.

type MsgHistoryData

type MsgHistoryData struct {
	MaxMessages int `json:"max_messages"`
}

type NodeCtx

type NodeCtx struct {
	Node      *FlowNode
	NodeID    string
	Inputs    []Message
	UserInput string
	Streaming bool
	Config    ExecuteConfig
	Result    *ExecuteResult
	Emit      func(StreamEvent)
}

NodeCtx is the everything-the-executor-needs bundle passed into every per-node Execute function.

type NodeResult

type NodeResult struct {
	Produced []Message
	Decision string
}

NodeResult is what an executor returns. Produced is the node's own contribution to the message flow (NOT the passthrough — downstream merging is handled by the engine via mergeInputs). Decision is set by question only.

type NodeType

type NodeType string
const (
	NodeUserPrompt   NodeType = "user_prompt"
	NodeSystemPrompt NodeType = "system_prompt"
	NodeMsgHistory   NodeType = "msg_history"
	NodeWebSearch    NodeType = "web_search"
	NodeLLM          NodeType = "llm"
	NodeQuestion     NodeType = "question"
	NodeSubflow      NodeType = "subflow"
	NodeUserOutput   NodeType = "user_output"
	NodeFiles        NodeType = "files"
	NodeCompact      NodeType = "compact"
)

type Position

type Position struct {
	X float64 `json:"x"`
	Y float64 `json:"y"`
}

type QuestionData

type QuestionData struct {
	Question      string   `json:"question"`
	Answers       []Answer `json:"answers"`
	Model         string   `json:"model"`
	MaxIterations int      `json:"max_iterations"`
}

type StreamEvent

type StreamEvent struct {
	Type              string      `json:"type"`
	NodeID            string      `json:"node_id,omitempty"`
	NodeType          string      `json:"node_type,omitempty"`
	Delta             string      `json:"delta,omitempty"`
	Output            string      `json:"output,omitempty"`
	OutputPreview     string      `json:"output_preview,omitempty"`
	ShowOutput        bool        `json:"show_output,omitempty"`
	Message           string      `json:"message,omitempty"`
	UserError         bool        `json:"user_error,omitempty"`
	MessageID         string      `json:"message_id,omitempty"`
	Usage             any         `json:"usage,omitempty"`
	TotalCost         string      `json:"total_cost,omitempty"`
	RetrySeconds      int         `json:"retry_seconds,omitempty"`
	Source            string      `json:"source,omitempty"`
	Content           string      `json:"content,omitempty"`
	Branch            string      `json:"branch,omitempty"`
	Title             string      `json:"title,omitempty"`
	Candidates        []Candidate `json:"candidates,omitempty"`
	GuestLLMCallsUsed *int32      `json:"guest_llm_calls_used,omitempty"`
	GuestLimitReached bool        `json:"guest_limit_reached,omitempty"`
}

StreamEvent is sent to the client during execution.

type SubflowData

type SubflowData struct {
	FlowID string `json:"flow_id"`
	Name   string `json:"name,omitempty"`
}

type SystemPromptData

type SystemPromptData struct {
	Text string `json:"text"`
}

type ValidationError

type ValidationError struct {
	NodeID  string
	Message string
}

ValidationError is returned by Validate when a specific node is misconfigured. Callers can use errors.As to extract the NodeID.

func (*ValidationError) Error

func (e *ValidationError) Error() string

type WebSearchData

type WebSearchData struct {
	ResultCount int `json:"result_count"`
}

Jump to

Keyboard shortcuts

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