Documentation
¶
Overview ¶
Package oi is a third agent engine for tomo, shaped after Open Interpreter: the model does not call structured tools, it writes a fenced code block and the engine runs it, feeds the output back, and loops until the model stops emitting code. The appeal is for weak or cheap models, which write a Python or shell block far more reliably than they emit well-formed function-call JSON, so a single run-this-code primitive removes the tool-calling failure mode entirely. It reuses tomo's provider, sandbox, and the default engine's Sink and Gate types, and carries its own system prompt (prompts/system.md), so it drops in wherever the default engine does.
Index ¶
Constants ¶
const ReproDirective = "Work reproduce-first. Before you change any source, turn the behavior the issue reports into a small, focused test: pick one concrete case the issue describes and write it as a script or test in a scratch file, separate from the project's own test suite. " +
"Run it against the unchanged code and confirm it FAILS: a reproduction that already passes is testing the wrong thing, and until you have a failing case you have not located the bug. " +
"Then make the smallest change that turns that test green, and rerun it to confirm. If more than one behavior is reported, add a case for each. The failing-then-passing test is your evidence the fix is real, not the fact that the code parses."
ReproDirective is an optional addendum that orients a model toward the reproduce-first workflow the reproduction gate (repro.go) enforces. The gate is the mechanism; this only tells the model the order of work up front so it does not have to discover it by being nudged. It asks the model to turn the reported behavior into a small focused test, see it fail against the current code, and only then fix until that test passes. Worded for any language and any task, it names no file or symbol from the issue, so it is general and not tailored. Appended only when the caller opts in, so it can be A/B'd.
const VerifyDirective = "Verification is not optional, and a check that never runs the code is not verification. " +
"A parser, compiler, type-checker, or linter that only reads the source proves the code parses, not that it works; it passes on code that errors the moment it runs (a Python `ast.parse` or `py_compile`, a `tsc --noEmit`, a `go vet`, printing \"syntax ok\"). " +
"Before you stop, execute what you changed in the repository's own language and tooling: load or import the unit you edited and call the changed function on a concrete input from the task, or run the project's own tests for the area you touched. " +
"If loading it raises, the call errors, or a test fails, that is your bug to fix in this run, not a result to report. " +
"An edit whose only check was that it parses or compiles is unverified, and while any named test still fails you are not done."
VerifyDirective is an optional addendum for the oi system prompt. The base prompt already asks for a check after each edit, but a model reliably reads "check" as "parse it" and ends a round on a file a parser accepts and a runtime error crashes: a syntax check passes on code that has never run. This directive closes that gap by demanding an executing check, one that actually loads the changed code or runs the touched tests, and by naming the weak checks that do not count. It is worded for any language, with the check names as examples rather than the whole rule, so it holds up once runs span more than Python. It is appended only when the caller opts in, so the default prompt is unchanged and the two can be A/B'd against each other.
Variables ¶
This section is empty.
Functions ¶
func ContextPack ¶
ContextPack is the symbol-anchored retrieval as a pure function of a workspace root and a task text, returning the preamble the engine injects once before the loop, or "" when there is nothing to add. It uses the dependency-free regex resolver. It is exported so a preview command and the labs A/B can drive the exact mechanism the engine uses rather than a reimplementation of it.
func ContextPackWith ¶
ContextPackWith is ContextPack with an optional language-server command. When lspArgv is non-empty and the server resolves the named symbols, their exact enclosing definitions and true references feed the pack; on any LSP failure, or when lspArgv is empty, it falls back to the regex resolver, so the caller is never worse off for asking.
Types ¶
type Engine ¶
type Engine struct {
Provider provider.Provider
Model string
System string
// Box runs a code block. A nil box is the unconfined default, so a caller that
// does not care about confinement can leave it unset.
Box sandbox.Sandbox
Gate agent.Gate
// Workspace is only carried for the audit trail and the sink; the sandbox
// already roots execution there.
Workspace string
// LSP is an optional language-server command (argv) used to resolve the
// context pack's symbols to their exact definitions and true references. Empty
// means the dependency-free regex resolver is used. Any server failure falls
// back to regex, so setting this never makes a run worse.
LSP []string
// MaxRounds caps the model calls in one turn. Zero is unbounded. A positive
// value bounds a probe or an A/B run, and stands in for OI's budget break.
MaxRounds int
// ExecGate arms the executing-check gate (gate.go): a turn that edited the
// worktree cannot end unless its last check actually ran the changed code and
// came back green, not merely parsed or compiled it. Off by default so it can
// be A/B'd against the softer prompt directive.
ExecGate bool
// Repro arms the reproduction gate (repro.go): a turn that edited the worktree
// cannot end green unless an executing check first came back red this turn, so
// the model must reproduce the reported bug as a failing test before its fix
// turns it green. Off by default so it can be A/B'd against the plain exec gate.
Repro bool
}
Engine runs the Open Interpreter loop for tomo: the model writes a fenced code block, the engine executes it in the workspace, feeds the output back, and loops until the model stops emitting code. It carries no tool registry, since its only action is run-this-code; execution goes straight to a sandbox. It reuses agent.Sink and agent.Gate so a caller drives it through the same interface as the default and cx engines.
func (*Engine) Turn ¶
func (e *Engine) Turn(ctx context.Context, history []provider.Message, user provider.Message, sink agent.Sink) ([]provider.Message, error)
Turn runs one user turn to completion and returns every message it generated, the user message first, so the caller can persist them. On error the messages so far come back too. The stop condition is Open Interpreter's: the turn ends when the model's reply carries no runnable code block, which is how the model signals it is done.