feat(agent): add-on system with rtk as the first built-in#2279
Draft
joshsny wants to merge 1 commit into
Draft
Conversation
5ce03ed to
750d4ae
Compare
Adds a typed add-on system to @posthog/agent and a `task.options.add_ons` configuration channel for opting in to extra agent behaviors per-task. Architecture - Unified registry, per-adapter capability honoring. `packages/agent/src/add-ons/` defines AddOnDefinition (name, options schema, contribute) and AddOnRegistry. Claude consumes every contribution slot (env / systemPromptAppend / preToolUse / postToolUse); Codex consumes only systemPromptAppend because codex-acp has no pre-execution tool interception. Add-ons that need command rewriting declare `supportedAdapters: ["claude"]` and are skipped on Codex with a log. - Single transport channel. Add-on config rides on `_meta.addOns` of the ACP newSession request, resolved in ClaudeAcpAgent.createSession and Codex's four session entry points. - Cloud parity. AgentServerConfig.addOns plus `--addOns <json>` on the sandbox agent server forward the same JSON to the cloud newSession. - First built-in: rtk. A Claude PreToolUse hook wrapping Bash commands through the rtk token-reduction CLI (rtk-ai/rtk). Resolution trusts $PATH; options: `binaryPath`, `skipPermissions`. - Task model. Adds an optional `options?.add_ons` field to the Task type in both agent-package and apps/code, ahead of the Django migration. Tests - 19 unit tests across registry.test.ts and rtk.test.ts. - 19 integration tests covering adapter wiring: PreToolUse ordering invariant (add-on hooks run before the built-in permission gate), systemPromptAppend composition across string + preset shapes, env merge with last-write-wins, appendToSystemPrompt branch coverage, addOns forwarded through all four Codex session entry points (newSession, loadSession, unstable_resumeSession, unstable_forkSession), env contribution dropped+warned on Codex. Merged in main (47 commits ahead) and resolved conflicts in options.ts (adding the add-on slots alongside cloudMode) and codex-agent.ts (composing applyAddOnContribution with applyStructuredOutput + applyLocalTools). Generated-By: PostHog Code Task-Id: de63edf0-0b52-40b4-9ffc-4758850b10d3
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.
Problem
PostHog Code tasks need a way to opt in to extra agent behaviors per-task. Today the only knobs are buried inside
claudeCode.optionsormcpServers, with no symmetric path that works for both local and cloud or for both Claude and Codex. The first concrete use case is rtk, a CLI proxy that wraps shell commands to reduce LLM token consumption, but the surface should support future capabilities (PostHog-aware system-prompt addenda, MCP-based integrations, etc.) without bespoke plumbing each time.Changes
Adds a typed add-on system to
@posthog/agentand atask.options.add_onsconfiguration channel.Architecture
packages/agent/src/add-ons/definesAddOnDefinition(name, options schema,contribute) andAddOnRegistry. The same registry is consumed by both Claude and Codex adapters; each honors only the slots it can:env,systemPromptAppend,preToolUse,postToolUsesystemPromptAppendonly —codex-acpexposes no pre/post-tool interception, so add-ons that need command rewriting declaresupportedAdapters: ["claude"]and are silently skipped on Codex._meta.addOnsof the ACPnewSessionrequest alongside the existingclaudeCode/jsonSchemachannels. Resolved inClaudeAcpAgent.createSession(Claude) andCodexAcpAgent.{newSession, loadSession, unstable_resumeSession, unstable_forkSession}(Codex).AgentServerConfig.addOnsand a matching--addOns <json>CLI flag on the sandbox agent server forward the same JSON onto the cloudnewSession.rtkAddOncontributes a ClaudePreToolUsehook that rewritestool_input.commandfor Bash tool calls intortk run [--skip-permissions] -- <original>. Options:binaryPath,skipPermissions. Binary resolution trusts$PATH.options?.add_onsfield to both the agent-packageTasktype and the apps/code sharedTasktype so the renderer and main process can populate it ahead of the Django migration.Hook ordering invariant
Add-on
PreToolUsehooks run BEFORE the built-in permission gate so a rewrite (e.g. rtk wrapping a Bash command) is visible to the permission check and to the cloud signed-commit guard.Follow-ups not in this PR
Taskmodel needsoptions = models.JSONField(default=dict, blank=True)plus a matching serializer field.task.options.add_onsis settable from code but there's no "Add-ons" disclosure in the task input form.How did you test this?
registry.test.tsandrtk.test.ts: empty config, env merging (last-wins),systemPromptAppendconcatenation, pre/postToolUse aggregation, adapter gating, unknown-name warnings, options-parse failures, prepare/contribute ordering, duplicate-registration rejection, Bash command rewriting, non-Bash pass-through,--skip-permissions, Codex adapter gating, end-to-end registry resolution, double-wrap protection, single-quote path escaping.buildSessionOptions: PreToolUse ordering invariant (add-on hooks BEFORE built-in permission gate), PostToolUse appending,systemPromptAppendacross both string and preset shapes, env merge with last-write-wins, no-contribution regression guard.appendToSystemPrompt: all four branches as a focused unit test._meta.addOnsforwarded to the registry on all four session entry points,systemPromptAppendconcatenated into_meta.systemPrompt, env contribution warned-and-dropped (codex-acp env is fixed at spawn), empty-contribution pass-through.pnpm --filter agent typecheckclean.Publish to changelog?
no
Created with PostHog Code