Fetches a repository's README from raw.githubusercontent.com, trying the main and master branches in parallel and selecting whichever returns HTTP 200. Runs five AI quality probes concurrently, averages two scores deterministically, routes through a quality lane, and appends a test-coverage warning when the AI detects no mention of tests.
What this example teaches
SelectStringOp, no try/catchAddFloatOp + DivFloatOp — once the AI returns two floats, all maths is deterministicSelectStringOp selects between an empty string and a warning message; StringConcatOp appends it — no conditional code in the driverStringTruncateOp) that caps input to 8 KB to stay within AI context limitsParallel fetches feed a preprocessing op; five probes fan out; deterministic averaging feeds quality lanes; an orthogonal bool gate injects a warning suffix.
Both fetch_main and fetch_master run without any condition — they always execute in parallel. IfIntEqOp converts the HTTP status to a boolean, and SelectStringOp acts as a pure data multiplexer: no imperative branching required.
// Both fetches run in parallel — no Condition on either vertex.
Vertex("fetch_main").Op("HTTPGetOp").
Input("URL", "main_url").
Output("Body", "main_body").
Output("StatusCode", "main_status").
Vertex("fetch_master").Op("HTTPGetOp").
Input("URL", "master_url").
Output("Body", "master_body").
// Was the main-branch fetch a 200?
Vertex("check_main").Op("IfIntEqOp").
Input("A", "main_status").
Input("B", "int_200").
Output("Match", "main_ok").
// Pick the body whose branch actually exists.
Vertex("pick_readme").Op("SelectStringOp").
Input("Cond", "main_ok").
Input("IfTrue", "main_body").
Input("IfFalse", "master_body").
Output("Result", "readme_raw").
After truncation, all five probes read from the same readme wire. With no mutual dependencies, the dagor engine schedules all five concurrently — five AI questions answered in roughly the time of one.
Vertex("purpose_op").Op("AIComputeStringToStringOp").
Params(map[string]string{"operation": "summarize the purpose in one sentence"}).
Input("Input", "readme").
Output("Result", "purpose_str").
Vertex("doc_score_op").Op("AIScoreOp").
Params(map[string]string{"criterion": "documentation completeness"}).
Input("Input", "readme").
Output("Result", "doc_score").
Vertex("has_tests_op").Op("AIBoolOp").
Params(map[string]string{"predicate": "does this README mention tests or CI?"}).
Input("Input", "readme").
Output("Result", "has_tests").
The average is computed with two op vertices — AddFloatOp sums the two score wires, and DivFloatOp divides by a constant wire. Both are typed library ops; no math lives in driver code.
Vertex("sum_scores").Op("AddFloatOp").
Input("A", "doc_score").
Input("B", "clarity_score").
Output("Result", "sum_scores_val").
Vertex("const_2").Op("ConstFloat64Op").
Params(map[string]string{"Value": "2.0"}).
Output("Result", "two_f").
Vertex("avg_score_op").Op("DivFloatOp").
Input("A", "sum_scores_val").
Input("B", "two_f").
Output("Result", "avg_score").
SelectStringOp acts as an in-graph ternary: when has_tests is true it routes an empty string; when false it routes the warning text. StringConcatOp appends whichever was selected. No if statements in the driver.
// Registered: operator.RegisterOpFactory("warning_const", builtin.ContextValFactory[string](warningKey{}))
// Injected: ctx = context.WithValue(ctx, warningKey{}, "\n\nWARNING: tests not mentioned")
Vertex("warning_const").Op("warning_const").
Output("Result", "warning_text").
Vertex("test_warning").Op("SelectStringOp").
Input("Cond", "has_tests").
Input("IfTrue", "empty_text"). // tests mentioned: no warning
Input("IfFalse", "warning_text"). // no tests: warning appended
Output("Result", "test_warning_str").
Vertex("final_narrative").Op("StringConcatOp").
Input("A", "narrative").
Input("B", "test_warning_str").
Output("Result", "final_narrative").
export CLAUDE_API_KEY=<your key>
# Live slug — main branch
go run ./examples/readme-quality/ --slug akennis/dagor
# Live slug — master branch fallback
go run ./examples/readme-quality/ --slug tj/n
# Offline fixture
go run ./examples/readme-quality/ --fixture examples/readme-quality/testdata/dagor.md
The same binary is dual-mode. Pass --mcp and instead of running once and exiting it speaks the Model Context Protocol over stdin/stdout, exposing the entire workflow as a single MCP tool, assess_readme. The Go SDK derives the tool's input schema from the workflow's UserInput struct and validates every tools/call request against it, so an agent runs the whole fetch → five-probe → score → verdict pipeline with one tool call.
# Speak MCP over stdin/stdout instead of running once
go run ./examples/readme-quality --mcp
Register it with any MCP client by pointing the client at that command:
{
"mcpServers": {
"readme-quality": {
"command": "go",
"args": ["run", "./examples/readme-quality", "--mcp"]
}
}
}
Measured on testdata/dagor.md. Input costs are high because the full README (~2,100 tokens) is re-passed as context to each of the six probes independently.
| Op | Calls | Input tokens | Output tokens | Total tokens |
|---|---|---|---|---|
| AIBoolOp | 2 | 4,275 | 8 | 4,283 |
| AIScoreOp | 2 | 4,303 | 14 | 4,317 |
| AIComputeOp | 2 | 4,300 | 311 | 4,611 |
| Total | 6 | 12,878 | 333 | 13,211 |