Add AGENTS.md - #256
Conversation
Notes from working on this repository and building a context against it. Covers the things that cost time to discover and are not visible from the source: where configuration and credentials actually resolve from, how context and skill discovery behave, and how to record a demo video of a Beaker session. The video section is the longest because Beaker is genuinely awkward to record, and each of the three pitfalls produces output that looks fine until you watch it. Waiting for the transcript to stop changing fires mid turn and stacks prompts on top of each other; End scrolls the query textarea rather than the transcript, so figures render off screen; and the agent will save a plot and load it back to describe it, which 404s on any model without image input. Every claim was checked against the current dev branch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01555XSwMPRxBZFAEsvubUMz
The credentials section was the weak point. The first version blamed shell environment variables for keys surviving isolation, which is only one of three mechanisms and not the one that actually bit. Now documents all three, each verified against the code and reproduced live: - Config.from_config_file loads a .env located by dotenv.find_dotenv(), which walks up from lib/config.py's own location. A .env anywhere above the install location injects variables into every run from that environment, regardless of cwd or $HOME. Reproduced: locate_envfile() from a venv three directories deep resolved to a repo-root .env. - Provider classes fall back to environment variables. - BeakerKernelManager sets the kernel's HOME and cwd to the agent user's passwd-database home, discarding the server's environment, so wrapping the server process isolates nothing that matters. Corrections to the first version: the cp -R recipe nested ui/ui on a second run (now rm -rf first); the skill search roots under "the working directory" and "the home directory" usually coincide because the kernel's cwd is set to the home; WEIGHT has no tie-break beyond dict order, so strictly-lowest is the requirement; the flicker claim about the Agent Running block is now phrased as the race it guards against rather than an observed behavior. New sections: version skew for downstream context authors (the SkillIntegrationProvider positional-argument meaning changed between 2.0.9 and this branch, silently), inspecting a live session through the REST endpoints, and stable Playwright selectors. GIF guidance now says to encode from the original webm. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01555XSwMPRxBZFAEsvubUMz
|
Pushed a red-team pass (11b7c52). The interesting outcome: the credentials section in v1 was wrong about the mechanism. I had blamed shell environment variables for API keys surviving isolation. Chasing it properly turned up three separate paths, each now verified against the code and one reproduced live:
Together these explain why a "first run with no key" is nearly impossible to fake on a developer machine, which is worth having written down. Also corrected from v1: the Still zero em dashes. |
Context setup runs before PythonSubkernel.setup(), whose init code ends with 'del importlib, os, site, sys'. Names a context setup procedure imports at top level are therefore gone before the first agent cell, and the failure surfaces later as a NameError inside helper functions. Found the hard way while building a context whose helper printed to sys.stderr. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01555XSwMPRxBZFAEsvubUMz
Notes from working on this repo and building a context against it. Aimed at the things that cost time to discover and are not visible from reading the source.
What's covered
Running from a checkout. The prebuilt frontend ships in the wheel as a build artifact and is gitignored, so an editable install serves no UI until you either run
make initor copy the assets out of an installed wheel. Also:uv runre-syncs fromuv.lockand silently replaces an editablebeaker-notebookwith the locked PyPI version, so a checkout under test appears to have no effect until you call the venv binary directly.Where credentials actually come from. Config resolution order, and the fact that a blank or missing config does not mean no key: provider classes fall back to environment variables, so
OPENAI_API_KEYand friends will satisfy an otherwise unconfigured install. Relevant if you are ever trying to reproduce a first-run experience, which needs an environment with none of them set.Contexts. Entry-point discovery and why moving a context needs a reinstall,
WEIGHTdeciding which context a session opens on, the two REST endpoints worth asserting against in tests, and procedures being Jinja templates.Skills. The
skills.jsonandskills/conventions, global roots attaching to every context, the trailing slash on remote URLs being load bearing, and skills failing to load silently (#254).Recording a demo video. The longest section, because Beaker is awkward to record and each pitfall produces output that looks fine until you watch it:
Agent Runningblock instead.keyboard.press("End")scrolls the focused element, which after typing is the query textarea, so the transcript never moves and figures render off screen.img[src^='data:image']verifies plotting actually worked.Plus ffmpeg recipes, and the note that GitHub strips
<video>from markdown so a README needs a GIF.Checked
Every claim verified against current
devrather than written from memory: config wording incli/config.py,WEIGHT = 10onDefaultContext,app/uiin the wheel artifacts,asyncio_mode = auto, the_get_skill_search_rootspatching in the skill tests, and the swallowed exception indiscover_integrations.Happy to cut anything that reads as too specific to my use case.