Add context layer for prompt assembly and tool execution gating#26
Merged
Conversation
Introduces src/context/ with two distinct concerns: - Static system prompt assembly: buildSystemContext composes discovered AGENTS.md/CLAUDE.md instructions, environment snapshot (cwd, shell, git), and tool guidance into a single string. Runs once at init so the system prompt stays stable for Anthropic prompt caching. - Dynamic per-step layers: withContext/applyContextLayers wrap any ToolSet with ContextLayer gates (beforeExecute) and transforms (afterExecute). Ships createExecutionPolicy (plan-mode blocking) and createOutputPolicy (truncation, redirection hints, optional disk stash). createPrepareStep composes compaction + context-status + plan-mode hints into an AI SDK PrepareStepFunction without ever mutating the system prompt. Also refreshes repo docs: - Rewrites root AGENTS.md as a contributor guide (dropped ~400 lines of consumer API examples that belonged in README), adds Core Principles section covering type safety, testability, error-return convention, and the folder-AGENTS.md documentation invariant. - Promotes root CLAUDE.md to a symlink -> AGENTS.md, matching the convention enforced everywhere else by scripts/check-agents-md.sh. - Adds src/context/AGENTS.md + CLAUDE.md symlink documenting internal architecture, design patterns, and common modifications. - Adds README section documenting buildSystemContext, layer composition, and prepareStep wiring, plus API reference entries for new exports. Test coverage: 7 new test files under tests/context/ covering layer wrapping, gate short-circuit, transform pipe, parallel isolation, output policy truncation/stash, execution policy, prepare step composition, and end-to-end integration with a real ToolSet. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Four spots used result.messages! without first narrowing result itself, which PrepareStepFunction types as PrepareStepResult | undefined. The surrounding expect(result?.messages).toBeDefined() doesn't propagate narrowing to TypeScript. Added explicit non-null assertions on result. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Clarifies that scripts use no hyphens (typecheck, not type-check) and lists the full set of package.json script names. Adds a one-liner for running all four pre-push CI gates locally. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The fallback branch in injectTruncatedOutput replaced the entire result
object with { _truncated, _hint }, silently erasing fields like { error }
and breaking the return-error-not-throw contract. Spread the original
result so all fields are preserved alongside truncation metadata.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The stashOutput mkdir -p call interpolated the directory path unescaped into a shell command, allowing spaces, $(), backticks, or semicolons in pathFor() results to break or execute unintended fragments. Single-quote the path with interior quote escaping. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Make planModeState optional in createExecutionPolicy so shouldBlock works standalone. Update createAgentTools wiring to install the layer when either plan mode or a custom execution policy is configured. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wrap the stash-to-disk path in try/catch so mkdir or writeFile failures log a warning instead of converting a successful tool result into an unhandled exception. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The JSDoc comments implied default-on behavior but the implementation disables both when omitted. Update comments to say so explicitly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
buildSystemContext called formatEnvironment without passing the custom fields from EnvironmentContextConfig, silently dropping them from the prompt output. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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
Introduces
src/context/— a new module that handles two concerns most agent loops end up reinventing:buildSystemContext) — discovers project docs (AGENTS.md/CLAUDE.md), captures an environment snapshot (cwd, shell, platform, git), and builds tool guidance. Runs once at init so the system prompt stays stable for Anthropic prompt caching.withContext/applyContextLayers) — wrap anyToolSetwithContextLayergates (beforeExecute) and transforms (afterExecute). ShipscreateExecutionPolicy(plan-mode blocking, custom deny predicates) andcreateOutputPolicy(truncation, redirection hints, optional disk stash).createPrepareStepcomposes compaction + context-status + plan-mode hints into an AI SDKPrepareStepFunctionwithout ever mutating the system prompt.New public API
Types:
ContextLayer,ExecutionPolicyConfig,OutputPolicyConfig,StashOutputConfig,InstructionDiscoveryConfig,DiscoveredInstructions,EnvironmentContext,EnvironmentContextConfig,ToolGuidanceConfig,SystemContextConfig,SystemContext,PrepareStepConfig.Functions:
withContext,applyContextLayers,createExecutionPolicy,createOutputPolicy,discoverInstructions,collectEnvironment,formatEnvironment,buildToolGuidance,buildSystemContext,createPrepareStep.All re-exported from
src/index.ts.AgentConfig.contextinsrc/types.tswires the layers automatically when provided.Docs refresh
AGENTS.mdas a contributor guide — drops ~400 lines of consumer API examples that belonged inREADME.md, adds a Core Principles section (type safety, testability, error-return convention, folder-AGENTS.md invariant), and documents the commit / lint / test / symlink CI gates.CLAUDE.mdto a symlink →AGENTS.md, matching the convention enforced everywhere else byscripts/check-agents-md.sh.src/context/AGENTS.md+CLAUDE.mdsymlink documenting internal architecture, design patterns, and per-task modification steps.README.mdwith three worked examples (building a system prompt, wrapping tools with layers, composingprepareStep) plus API Reference entries for all new exports.Test coverage
7 new test files under
tests/context/(2,089 lines total):build-context.test.ts— system prompt assembly, section enable/disable, combined outputexecution-policy.test.ts— plan-mode blocking, custom predicatesoutput-policy.test.ts— truncation, hints, stash-to-disk, custom buildersprepare-step.test.ts— compaction, context-status injection, plan-mode hint,extendcompositionwith-context.test.ts— layer wrapping, gate short-circuit, transform pipe, no-execute passthroughparallel.test.ts— layer isolation under concurrent tool callsintegration.test.ts— end-to-end with a realToolSet+ sandboxFull suite: 558 passed, 27 skipped (sandbox smoke tests).
Breaking changes
None. All new surface is additive — existing
createAgentToolssignatures unchanged, no tool input/output schemas touched, noSandboxinterface changes.Test plan
bun run typecheck— cleanbun run check:ci(Biome) — cleanbun run check:agents— cleanbun run test— 558 passed, 27 skippedexamples/basic.tswith the newbuildSystemContext+applyContextLayerswiringbuildSystemContextcreatePrepareStepcompaction path under a long conversation🤖 Generated with Claude Code