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