Skip to content

refactor(pipeline): Graph model uses map[string]string for all config (Primitive Obsession) #19

@harperreed

Description

@harperreed

Summary

The Graph.Node.Attrs field is a map[string]string that carries all node configuration — prompts, models, providers, retry config, timeouts, fidelity, etc. This is the root cause of multiple bugs found in this review.

Problems

  1. Silent key mismatches — The adapter writes model, the handler reads llm_model. No compile-time check catches this. (See fix(pipeline): attribute key mismatch — model/provider/fallback_target silently ignored for .dip files #13)
  2. No type safetymax_retries stored as string, parsed back with strconv.Atoi scattered through handlers
  3. Impedance mismatch — The dippin IR has typed structs (AgentConfig, ToolConfig), but the adapter immediately flattens them to strings, discarding type information
  4. Shotgun surgery — Adding a new config field requires touching the adapter, engine, and every handler with nothing but convention connecting them
  5. DOT shapes as routing mechanismshape is a visual presentation concept from DOT that has been promoted to a domain routing mechanism (shape -> handler)

Current Architecture

DippinIR (typed) → Adapter → map[string]string → Handler → strconv.Atoi back to typed

Recommended Architecture

DippinIR (typed) → Adapter → NodeConfig (typed) → Handler (direct use)

Define typed config structs in pipeline package. DOT parser does string-to-struct conversion. Handlers consume typed configs directly.

Migration Path

  1. Define NodeConfig interface with AgentNodeConfig, ToolNodeConfig, etc. in pipeline
  2. Add typed fields to Node struct alongside Attrs (backward compatible)
  3. Migrate handlers one at a time to read typed fields
  4. Eventually remove Attrs bag

Sources

Found by: Martin Fowler (x2), OpenAI Researcher, Architecture Expert, Grad Student AI Researcher (expert panel review)

This is the highest-value long-term architectural investment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3: lowNice to have, no urgencyarea/enginePipeline execution enginerefactorCode quality improvement, no behavior change

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions