templates: restore per-iter frames via pinned IpoptOptions.intermediate_callback (#177) - #184
Merged
Merged
Conversation
…te_callback (#177) Re-wires pulse_emit (LivePulsePlotCallback delegate -> iter_*.png + AMICODE_PULSE + STOP poll) in all four templates through the intermediate-callback API that the pinned DirectTrajOpt actually exposes — undoing the #157 removal now that the bundle pin has the hook. API verification (AC3), against the pin rather than docs: - julia/Manifest.toml (repo copy == provisioned ~/.amico/julia copy) pins DirectTrajOpt 0.9.7, git-tree-sha1 c722d301a8d064de5d9ab67e5bc8a1dff893683a, identical to `git rev-parse v0.9.7^{tree}` in DirectTrajOpt.jl. - At that tree, src/solvers/ipopt_solver/options.jl declares `intermediate_callback::Any = nothing` on IpoptOptions; solver.jl's `_ipopt_callback_function` wraps it via Callbacks.callback_intermediate_factory into `(primal, iter) -> Bool` (full NLP primal, restoration phase skipped) and composes it with the raw `callback` — all fire per IPM iteration, solve continues iff all return true. - Runtime check in the provisioned project: pkgversion(DirectTrajOpt) == 0.9.7, hasfield(IpoptOptions, :intermediate_callback) == true. The hasfield guard is the #157 lesson: a cloud bundle still baked with DTO <= 0.9.6 lacks the field (the kwarg MethodError that killed cloud solves), so the template degrades to stats-only (AMICODE_ITER flows, frames dark, @warn) instead of crashing before the solve. Zero run-dir contract drift: PulseEmitCallback, cb_log, PLOT_EVERY, frame names (LivePulsePlotCallback's iter_NNNNN.png) untouched; the HP template's bare `using Piccolissimo` cloud-wrapper marker preserved. Verified locally: bounded mini-solve (max_iter=12) of solve_template.jl under julia --project=$HOME/.amico/julia — iter_00000/00006/00012.png written, 13 AMICODE_PULSE + 13 AMICODE_ITER lines, result.toml + pulse.jld2 + DONE, no MethodError. All four templates parse clean. Staging cloud solve (AC2) deferred to a live run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Sep 2, 2026
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.
Summary
Closes #177. Restores the per-iteration frame emitter (
pulse_emit) in all four solve templates via the intermediate-callback hook that the pinned DirectTrajOpt 0.9.7 exposes (julia/Manifest.tomlgit-tree-sha1c722d301a8d0…==v0.9.7^{tree}— verified against the package source, not docs).IpoptOptions(intermediate_callback = pulse_emit)→iter_<N>.png+AMICODE_PULSEper IPM iteration + STOP poll, composed with the existingcb_logstats callback.hasfield-guarded (the templates: fix cloud-solve blockers (Ipopt callback + bare using Piccolissimo) #157 lesson): a cloud bundle still baked with DTO ≤ 0.9.6 degrades to stats-only (AMICODE_ITERstill flows, frames dark, one @warn) instead of dying on a kwarg MethodError before the solve.skeleton_free.jl,solve_rydberg_cz.jl,solve_template.jl,solve_template_hp.jl.Verification (live bounded mini-solve, pinned julia env)
iter_00000.png / iter_00006.png / iter_00012.pngproduced;AMICODE_PULSE+AMICODE_ITERemitted every iteration;pulse.jld2+result.tomlwritten; run completedDONE fidelity=0.744with no MethodError.🤖 Generated with Claude Code