Repository navigation
feat: dream cost emails, and a general API task runner for other scheduled prompts - #46
Merged
Merged
Conversation
Adds src/dream-runner/, a standalone runner that executes prompts/dream-nightly.md through the Claude Messages API with an Anthropic API key, instead of as a Claude Code scheduled task on a claude.ai plan. - Spawns the MCP server over stdio for the graph tools, adds file tools confined to ~/graph-memory (rw) and ~/.claude/projects (ro); no shell. - Reads the key at run time from ANTHROPIC_API_KEY or ANTHROPIC_API_KEY_FILE (file or one-file folder); never logged or passed to the MCP child. - Skips the API entirely when nothing is pending; holds dream.lock itself; prompt caching, context editing, per-run cost cap with a wrap-up turn. - Opt-in graph-dream compose service (profile "dream", daily at DREAM_SCHEDULE) and scripts/register-dream-task.ps1 for Task Scheduler. - Docs in docs/DREAM_PROCESS.md "API-key runner"; tests for the loop, path confinement, key parsing, pending check and schedule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo1icT3VB2uwkk8m5RAaWH
…e manifest entries The first live run spent its whole $3 budget listing ~/.claude/projects and paging through the 500 KB manifest, and extracted nothing. - The runner now passes the exact pending list (session id, path, new or delta, previous processed_at) in the first message; the notes tell the model not to list the projects folder or read the manifest. - read_transcript pages through a session with the canonical parser and applies the delta filter before anything reaches the model; it replaces graph_read_transcript, which is now excluded by default. - update_manifest merges one entry on disk with the watermark captured at read time, instead of the model rewriting the whole manifest. - Sessions modified in the last 30 minutes are left for the next run. - Wrap-up starts at 80% of the budget; hard stop at 1.5x. - Smaller default result and read sizes (40k / 30k chars). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo1icT3VB2uwkk8m5RAaWH
- `--job weekly` runs prompts/weekly-maintenance.md with its own tool list (graph_export, graph_cypher and graph_prune allowed; graph_merge hidden), its own budget (DREAM_WEEKLY_MAX_COST_USD, default $1.50) and runner notes. No pending check; lock source api-runner-weekly. - Step 12's email needs a shell and gws, so the runner skips it and the report says so. Off by default (DREAM_WEEKLY_SCHEDULE=off) so it doesn't double up with the Claude Code weekly task. - Daemon schedules both jobs, each with its own next slot; schedules accept "HH:MM" or "Sun HH:MM". - register-dream-task.ps1 takes -Job weekly -DayOfWeek. - Log the ids of sessions held back as still active. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo1icT3VB2uwkk8m5RAaWH
The runner, not the model, sends mail after a run: the weekly report when the weekly job completes, and a short alert (outcome, cost, log tail) when any run errors, stops at its budget or turn limit, is refused, or finds the lock held. Normal nightly runs send nothing. Plain SMTP via nodemailer (Gmail app password by default), with the password read from a mounted file like the API key. Off unless DREAM_ALERT_TO, DREAM_SMTP_USER and the password file are set. A failed send is logged and doesn't fail the run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo1icT3VB2uwkk8m5RAaWH
Replace SMTP with a POST to gws-mcp's send-only /notify endpoint over the shared mcp-notify network, authenticated by a token file. The runner no longer holds a Gmail credential; gws-mcp fixes the sender and recipient. Drops nodemailer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo1icT3VB2uwkk8m5RAaWH
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo1icT3VB2uwkk8m5RAaWH
Nightly runs now mail a summary (sessions, entities, edges, the model's closing note) with the run's cost; quiet nights send a one-liner. Every mail, the weekly report included, opens with the run's cost and the API spend so far this month from runs.jsonl. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo1icT3VB2uwkk8m5RAaWH
task.js runs one scheduled prompt on the API key with only what its task file grants: confined file tools, allowlisted commands (fixed exe and args, one pattern-checked argument), allowlisted URLs with credentials injected by the runner, allowlisted stdio MCP tools, and email through a gws-mcp notify profile. Runs share the dream's runs.jsonl so month-to-date spend covers them. Adds register-api-task.ps1 for Task Scheduler. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo1icT3VB2uwkk8m5RAaWH
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo1icT3VB2uwkk8m5RAaWH
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo1icT3VB2uwkk8m5RAaWH
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo1icT3VB2uwkk8m5RAaWH
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.
Requested by Steve · project thread
What
This follows #45 and has two parts.
1. A cost summary after every dream run
Graph dream — <date>: N sessions, E entities, D edges (~$cost). The body has the countsupdate_manifestrecorded, what discovery found, and the model's closing message.nothing new (~$0.00).Cost: ~$X (N turns, model)andAPI spend this month: ~$Y over K runs. The month figure is summed fromlogs/dream-runner/runs.jsonl.2.
task.js: a general API task runnerIt runs one scheduled prompt (a Claude Code SKILL.md, say) on the API key, with only the capabilities its JSON task file grants. There is no shell.
list_dirandread_filework anywhere underworkdir.write_fileandedit_filework only underwrite_paths. Symlinks out of the folder are refused.http_requestreaches only the listed prefix and method pairs. The runner injects bearer tokens and{{VAR}}values read from files, so the model never sees them. Redirects aren't followed, and URLs with userinfo are refused.send_emailgoes through a gws-mcp notify profile, which fixes the sender and recipient. Sends are capped per run.scripts/register-api-task.ps1sets up a Task Scheduler job. Tasks run on the host so they can use local tools like python or an MCP server's.exe.Task files and their prompts live on the host, outside this repo.
The branch also carries
-s oursmerges of its pre-squash #45 history, so it could be reused without a force push. Those merges change no files.Testing
tscis clean.src/dream-runner: 27/27 tests pass.🤖 Generated with Claude Code
https://claude.com/claude-code