| Name | Last commit date | |
|---|---|---|
| .. | ||
| constants | ||
| git | ||
| llm | ||
| runners | ||
| utils | ||
| config.ts | ||
| constants.ts | ||
| logger.ts | ||
| model-catalog.ts | ||
| path-utils.ts | ||
| prr-runtime-meta.ts | ||
| README.md | ||
| run-with-concurrency.ts | ||
| timing.ts | ||
| token-tracking.ts | ||
Shared library
Code shared across prr, pill, story, split-exec, and split-plan. This README covers modules that have non-obvious design or WHYs.
utils/tokens.ts — Token estimation and truncation
Purpose: Single source of truth for token budgeting (chars-per-token) and for truncating long text while keeping head and tail visible.
Exports:
CHARS_PER_TOKEN(4) — Rough chars per token for budgeting. WHY: Same constant everywhere avoids drift; aligns withshared/llm/model-context-limits.tsand provider docs.estimateTokens(text)—Math.ceil(text.length / CHARS_PER_TOKEN). WHY: Good enough for context budgeting; not used for billing. Prr (prompt size checks), pill (log caps), and story-read (chapter sizing) all use this.truncateHeadAndTail(text, maxTokens, marker?)— Truncates to ~maxTokens chars, keeping head (2/3) and tail (1/3) with an optional marker in between. WHY: Start and end of logs/docs are highest signal; middle is often repetitive. Callers (e.g. pill) can pass a custom marker for audit messages (e.g. "504 timeout avoidance").truncateHeadAndTailByChars(text, maxChars, marker?)— Same idea with a character cap. WHY: Hard char caps (e.g. 50k for pill output log) avoid gateway 504 / FUNCTION_INVOCATION_TIMEOUT when token estimates undercount.
WHY Math.max(0, …) for tailChars: When the marker is long, tailChars = maxChars - headChars - marker.length can go negative. text.slice(-tailChars) with negative would be wrong. Clamping to 0 yields an empty tail but valid output.
llm/story-read.ts — Chapter-by-chapter summarization with carried context
Purpose: Summarize long text (e.g. output.log, prompts.log) by splitting into chapters, sending each to an LLM with compressed context from previous chapters, and merging state (open questions, predictions, threads) into a final digest. Used by pill for large logs; reusable by any tool that needs to summarize huge logs or documents without losing narrative.
Concepts:
- Chunking:
chunkPlainText(text, chapterTokenBudget)splits on line boundaries so chapters are readable and we never split mid-line. WHY line boundaries: Logs and docs are line-oriented; splitting mid-line would send broken context to the model. - Single line over budget: If one line exceeds the chapter token budget and the current chapter is empty, we emit that line as its own chapter. WHY: Otherwise one giant line (e.g. a 50k-token minified blob) would become one oversized chapter and blow the model's context.
- Prior context: Before each chapter we pass compressed "open questions", "active predictions", and "story so far" (threads). WHY: The model builds understanding progressively; without carried context each chapter would be analyzed in isolation and the digest would lose narrative.
- Default system prompt: Asks for JSON with observations, answeredQuestions, newQuestions, refutedPredictions, threads, etc. WHY: Structured output lets us merge state and build a consistent digest; the prompt is tuned for "log from a software tool run" but can be overridden via options.
- onChapterError:
'break'(default),'skip', or'throw'. WHY: One bad chapter shouldn't kill the whole run; break returns digest so far; skip continues with empty analysis for that chapter.
Exports: chunkPlainText, storyReadChapters, storyReadPlainText, parseChapterAnalysis, ChapterAnalysis, StoryReadClient, StoryReadOptions. Pill's processor.ts wires its log formats (plain text, prompts.log pairs) to these; the core loop and schema live here so other tools can reuse them.
Other shared modules
logger.ts— Output log tee, prompts log, debug, formatNumber. See main README and pill README for pill hook and WHY dynamic import.config.ts— Loads .env, validates config. Used by prr, story, split-exec, split-plan.PRR_THINKING_BUDGETabove 500,000 clamps with a warning (typo guard).constants.ts— LLM limits, batch sizes,ELIZACLOUD_SKIP_MODEL_IDS/ELIZACLOUD_SKIP_REASON(authoritative ElizaCloud skip list), session-skip envs. Operator snapshot: docs/MODELS.md (“Rotation order and skip list”). Overrides:PRR_ELIZACLOUD_INCLUDE_MODELS,PRR_ELIZACLOUD_EXTRA_SKIP_MODELS(root README).llm/— rate-limit, elizacloud, model-context-limits. Used by prr and pill.git/— Clone, merge, commit, push, conflict detection. Used by prr and split-exec. Recovery /scanCommittedFixes: see AGENTS.md / DEVELOPMENT.md (nogit-hooks.tsin this tree — hooks live in product repos).runners/— llm-api, cursor, aider, etc. Used by prr fixer lane.
See CHANGELOG for WHYs on recent shared changes (tokens, story-read, thread replies, pill 504 avoidance).