Repository navigation
Fix #251: session handoff file for long-running work - #257
Merged
Merged
Conversation
--handoff / handoff.enabled reads .tinyagent/handoff.md into the first message as data, runs an optional handoff.startup_command before the first turn, and rewrites the file with the task, status and final answer when the run ends. Docs: README, subcommands, config, json-output, long-runs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #251
Summary
Adds an opt-in session handoff for long-running work, following the long-running harness pattern from the issue:
--handoff/handoff.enabled: true(off by default;--handoff=falseturns it off)..tinyagent/handoff.md(configurablehandoff.path) and places it before the task in the first user message inside a<session_handoff>block that labels it as data from earlier sessions, not instructions (AGENTS.md and the task outrank it), like project memory. Capped byhandoff.max_bytes(16 KiB), with a truncation marker. A missing file tells the model it's the first session.handoff.startup_command, run withsh -cin--cwdbefore the first turn, bounded byhandoff.startup_timeout_seconds(120); its exit code and the tail of its output (handoff.startup_max_output, 8 KiB) are given to the model as data. Failures warn and the run continues.--jsonevents:handoff.loaded,handoff.startup,handoff.saved(no file text or command output).New code lives in
internal/handoff,internal/config/handoff.goandcmd/tinyagent/handoff_run.go;main.goonly gets the flag field, the override, and two calls.agent.Agentgains aTaskPreamblefield so the handoff rides in the first user message (t.Taskstays the bare task and resume needs no system-prompt reconstruction).Decisions on open questions
-cor a profile (never the repository), so a repo can't set a startup command.handoff.pathmust be relative and stay inside--cwd.--resume/follow-ups replay it from the checkpoint and don't reload, rerun or rewrite anything.--read-onlyruns load the file but skip the startup command and don't rewrite the file.--acpsessions don't use the handoff.Testing
gofmt -l .clean;go build ./...,go vet ./...,go test -count=1 ./...pass.internal/handoff(load/truncate, preamble wrapping, render/write, startup exit code/tail/timeout),internal/config(defaults off, YAML parsing, validation errors),cmd/tinyagent(off by default, write-then-load across two runs, startup command output in context + JSON events + custom path,--handoff=false, read-only leaves the file).Docs updated
--handoff)handoff:keys)