← Library AI AI-Powered

ModeSelectOp

AI-powered single-label classifier — maps input text to exactly one category, designed to drive multi-branch workflow routing.

Inputs

Field Type Description
Input *string Text to classify into a single mode

Outputs

Field Type Description
Result string Exactly one category from the configured set

Reasoning is captured by WithReasoningLog — no graph output needed.

Params

Key Type Default Description
categories string required Comma-separated list (minimum 2)
max_retries string "3" Number of retries on parse error

Typical Use Cases

  • Intent classification for multi-branch routing
  • Query type detection (FAQ vs complaint vs general)
  • Department routing (billing / technical / sales)
  • Mode selection in multi-mode workflows

Always returns exactly one category. Unlike AIClassifyMultiLabelOp which can return zero or more labels, ModeSelectOp is guaranteed to return one. Use it as a switch/dispatcher node to drive mutually exclusive branches.

Pair with IfStringEqOp. Wire the Result into multiple IfStringEqOp nodes (one per mode) to create clean branch conditions for each downstream path.

Complete Runnable Example

Routes a customer support message to one of three departments: billing, technical, or sales.

main.go
package main

import (
	"context"
	"encoding/json"
	"log"
	"os"
	"time"

	"github.com/akennis/sparsi-go/library"
	_ "github.com/akennis/dagor/operator/builtin"

	"github.com/panjf2000/ants/v2"
	"github.com/akennis/dagor"
	"github.com/akennis/dagor/graph"
)

func main() {
	msg := "I was charged twice for my subscription last month."
	library.RegisterConst("user_message", msg)

	g, err := graph.NewBuilder("mode_select_demo").
		Vertex("msg_src").Op("user_message").Output("Result", "msg_wire").
		Vertex("route").Op("ModeSelectOp").
		Params(map[string]string{
			"categories": "billing,technical,sales",
		}).
		Input("Input", "msg_wire").
		Output("Result", "department").
		Build()
	if err != nil {
		log.Fatalf("build: %v", err)
	}

	pool, err := ants.NewPool(4)
	if err != nil {
		log.Fatalf("pool: %v", err)
	}
	defer pool.Release()

	eng, err := dagor.NewEngine(g, pool)
	if err != nil {
		log.Fatalf("engine: %v", err)
	}

	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
	defer cancel()

	if err := eng.Run(ctx); err != nil {
		log.Fatalf("run: %v", err)
	}

	out := map[string]any{
		"message": msg,
	}
	if raw, ok := eng.GetOutput("department"); ok {
		out["department"] = *raw.(*string)
	}

	enc := json.NewEncoder(os.Stdout)
	enc.SetIndent("", "  ")
	enc.Encode(out)
}