effort

package
v0.4.2-rc.2 Latest Latest
Warning

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

Go to latest
Published: Sep 30, 2026 License: Apache-2.0 Imports: 1 Imported by: 0

Documentation

Overview

Package effort is the reasoning-depth ladder: five named rungs, one resolver, and nothing else.

It exists because "how hard should the model think about this" was already being answered in half a dozen unrelated places — a level held per model id on the session, a `:high` suffix on a crew tier value, a hardcoded effort at every errand and sentinel — and each of them was a different vocabulary for one question. A person who dialled their conversation up found their tasks unchanged, and a lane adding the next spawn site had nowhere to look for the answer.

So the ladder is written down ONCE, here, and the answer is computed ONCE, by Resolve. Every model call in this process reads its depth through that function; a spawn site that decides for itself is the defect this package was written to end.

THIS PACKAGE HOLDS NO PROVIDER VOCABULARY AND IMPORTS NOTHING. A rung is a word about how hard to think, not a request field: translating one into the shape a wire accepts is the adapter's job and happens nowhere above it (internal/provider's effortladder.go). That is what lets the ladder grow a rung the wire has no word for.

Index

Constants

View Source
const Ship = None

Ship leaves reasoning to the selected model unless a person chooses a rung. Keeping this as absence lets provider defaults evolve without a local model table or an instruction that enables, disables, or budgets thinking.

Variables

View Source
var Rungs = []Rung{Low, Medium, High, XHigh, Max}

Rungs is the ladder, cheapest first.

THERE ARE FIVE AND THERE WILL NEVER BE A SIXTH. A ladder somebody can add a step to is a ladder nobody can learn: every surface that draws it, every setting that stores it and every person who has memorised where their work sits would move together for one more shade of the same idea. A new rung has to displace an existing one, in this slice, in one commit.

Functions

This section is empty.

Types

type Role

type Role string

Role is what the call is FOR, and it is the rung of last resort: the answer when nobody has said anything more specific.

It exists because the honest default is not one number. A person's turn and the work they handed out deserve the depth they configured; the machinery that runs while nobody is watching does not, and a sentinel deliberating for a minute over "has CI gone red" is money spent on a yes-or-no.

const (
	// RoleChat is a person's own turn in the conversation.
	RoleChat Role = "chat"

	// RoleWorker is a task, a part of a divided task, or an adaptive-run node —
	// work the person handed out, which is their work at one remove and gets
	// their depth.
	RoleWorker Role = "worker"

	// RoleWork is a task worker on the bash belt (internal/session's
	// bashbelt.go): the same work at one remove as [RoleWorker], but on a belt
	// whose one action per response spends the worker's depth again on every
	// round of a run. The seat holds a floor of [Low], so the depth the person
	// configured is not paid several times over for the same thinking; a rung
	// set on the task, the conversation or the turn still outranks it.
	RoleWork Role = "work"

	// RoleErrand is the session's own housekeeping: naming a conversation,
	// summarising it, judging a route. THE PERSON'S DIAL IS NOT SPENT ON THESE
	// and neither is a default — a rung somebody set so their question would be
	// thought about would be an odd thing to spend on titling it.
	RoleErrand Role = "errand"

	// RoleStanding is one firing of a standing item, running unattended. It
	// carries no floor of its own: what keeps a firing from inheriting a depth
	// nobody meant it to have is that the conversation's dial does not reach it
	// (see [roleFloor]).
	RoleStanding Role = "standing"

	// RoleSentinel is the yes-or-no in front of a firing: has the thing the
	// person asked about happened? It is a judgment on evidence already
	// gathered and it runs on every check of every item forever — so the item's
	// own rung is the only thing that ever asks it to think, and an item that
	// asked for nothing sends nothing.
	RoleSentinel Role = "sentinel"
)

type Rung

type Rung string

Rung is one step of the ladder.

const (
	// None is absence rather than a rung. Nothing is asked for and the model
	// thinks however it thinks, which is what an unconfigured install sends and
	// the only value that leaves a request byte-for-byte what it was.
	//
	// It is NOT "think as little as possible" — that is a different request, it
	// suppresses the thinking pass outright, and some endpoints refuse it. The
	// adapter owns that shape and this ladder never reaches for it.
	None Rung = ""

	Low    Rung = "low"
	Medium Rung = "medium"
	High   Rung = "high"

	// XHigh and Max are the two rungs above the word ladder every provider
	// shares. "high" is the top of that vocabulary and there is nothing above it
	// to SAY, so these two say it with a thinking budget instead — see the
	// constants in internal/provider for the figures and why they are those.
	XHigh Rung = "xhigh"
	Max   Rung = "max"
)

func Parse

func Parse(value string) (Rung, bool)

Parse normalizes one operator-supplied word and reports whether it is one.

"auto", the legacy alias "off", and "" land on None. At a scoped dial this clears the override; at the install default it leaves reasoning to the provider. An unrecognized word is refused rather than quietly downgraded: a typo that silently drops a rung somebody paid for is worse than a message saying the word is not one.

func Resolve

func Resolve(scope Scope) Rung

Resolve is the whole precedence rule, and it is short on purpose: turn beats conversation beats task beats role beats the install's default.

TASK SITS BELOW CONVERSATION and not above it, which is the one ordering somebody will want to argue with. The reason is where each one is set from: a conversation rung is a person leaning on the dial in front of them right now, and a task rung is a decision made when the work was handed out, possibly days ago and possibly by the model. The nearer hand wins.

func (Rung) String

func (r Rung) String() string

String is the rung as a person and a config file both spell it, and "" for None — which is what an empty setting looks like on disk and what the emptiness law asks a surface to draw as nothing at all.

func (Rung) Valid

func (r Rung) Valid() bool

Valid reports whether a rung is one of Rungs. None is not: it is absence, and a caller asking "is this a rung" about absence wants no.

type Scope

type Scope struct {
	// Turn is a rung for this one call and nothing after it. In the
	// conversation it is the level dialled onto the model now in use, re-read at
	// the top of every turn — which is why a change made mid-turn lands on the
	// next one and never half-way through the one in flight.
	Turn Rung

	// Conversation is the rung this session was set to, sticky across restarts
	// (session.Meta's `effort`).
	Conversation Rung

	// Task is the rung set on the piece of work this call belongs to
	// (the task checkpoint's `effort`, a standing item's `does.effort`).
	Task Rung

	// Role is what the call is for. It decides nothing when a scope above it
	// spoke; it decides everything when none did.
	Role Role

	// Default is the install's own rung — the `effort` settings row, [Ship] when
	// nobody has chosen. It is last because it is the answer to "and otherwise?".
	Default Rung
}

Scope is everything that has an opinion about one call's depth, most specific first. Every field may be None, which means "this scope said nothing".

Jump to

Keyboard shortcuts

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