Repository navigation
Add experimental Grok Build (grok) host - #148
Merged
Saksham Uboweja (SakshamUboweja) merged 4 commits intoNov 6, 2026
Merged
Saksham Uboweja (SakshamUboweja) merged 4 commits into
Saksham Uboweja (SakshamUboweja) merged 4 commits into
Conversation
grok 1.0.70 runs Claude Code's installed plugins and sends Claude's snake_case hook keys, so TokenEconomizer already ran inside grok sessions and was misdetected as Claude Code (wrong session log, tool names and side calls). detect() now recognises grok first (it alone sends hookEventName; its sessions live under ~/.grok/sessions). Verified live on grok 1.0.70: - Bash results carry `output` as a list of byte ints; the adapter reads output_for_prompt and exit_code instead. - An extra observe-only Stop (reason "shutdown", no promptId) follows SessionEnd and is ignored; StopCancelled/StopFailure close the turn as not normal. - SessionStart context never reaches the model (only a person-facing systemMessage is read there), so the start context is delivered once with the session's first PostToolUse additionalContext, which does. - Usage comes from the session's usage.json (inputTokens includes cached reads); side calls run through `grok -p --output-format json`. Micro-skills, the loop guard and the session ledger are supported; tool pruning is not. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A deny list naming grok's shell as run_terminal_cmd removed nothing (its shell is run_terminal_command), and grok -p runs in auto permission mode, so a side call whose prompt quotes session commands could run a shell command. Verified on 1.0.70 that the allowlist leaves only read_file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
|
Thanks, this looks good and I'm happy to merge it. A few small things first: The sidecall.py module docstring still says the Grok side call removes tools with --disallowed-tools. It now uses the --tools read_file allowlist, so please update it. docs/PLUGIN.md also lists the side call's flags as not exercised, but 4f9af7f says they were verified on 1.0.70. |
…nto feat/grok-host # Conflicts: # README.md
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
Thanks! Addressed in 84418df:
|
Saksham Uboweja (SakshamUboweja)
merged commit Nov 6, 2026
ce9cf65
into
microsoft:main
9 checks passed
This was referenced Nov 6, 2026
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.
Closes #145.
Grok 1.0.70 loads Claude Code's installed plugins and runs their hooks. So TokenEconomizer installed for Claude Code already runs inside grok sessions, where
hosts.detecttreated them as Claude Code: the wrong session log, tool names and result shapes, and side calls throughclaude -p. This PR adds agrokhost and makesdetectrecognise grok first. Grok alone sendshookEventName, and its sessions live under~/.grok/sessions/. Environment variables decide only when the payload has no transcript path, so a Claude Code session started from a grok shell stays Claude Code. Supported: micro-skills, the loop guard and the session ledger. Not supported: tool pruning.Grok behaviours the host handles (verified live on 1.0.70)
tool_response.outputis a list of byte ints. The host reads the text fromoutput_for_promptand the exit code fromexit_code.Stop(reasonshutdown, nopromptId) fires afterSessionEnd. It is ignored.StopCancelledandStopFailureclose the turn as not normal.promptIdis onUserPromptSubmitandStopbut not on tool events.SessionStartcontext never reaches the model. Only a person-facingsystemMessageis read there, which I verified with a codeword.PostToolUseadditionalContextdoes reach the model, so the start context is delivered once, with the session's first tool call.usage.json, whereinputTokensincludes cached reads, so fresh input isinputTokens - cachedReadTokens. xAI ids aren't inpricing.py, so the ledger uses its labelled fallback.Side calls
grok -p … --output-format jsonruns in a throwaway directory withTE_SIDECALL=1.grok -pruns inautopermission mode, so the call uses a tool allowlist:--tools read_file, with grok's MCP dispatchers removed and deny rules for Bash/Edit/Write/Web/Task behind it.A deny list does not fail closed here. Live,
--disallowed-tools run_terminal_cmd(the name in grok's docs example) removed nothing and the shell command ran; grok's real shell tool isrun_terminal_command.--tools ""is read as no filter at all. With the allowlist, the side call's owntool_definitions.jsonlists onlyread_file, and a prompt asking for a shell command and a file write left its directory empty.Verification
python -m pytest tests experiments/tests: 1119 passed, 18 skipped (28 new tests intests/test_grok.py, fixtures built in code).grok -prun with the plugin's Claude Code hook file (no--host) installed as project hooks, with an isolatedTOKENECONOMIZER_HOME:Stopwas ignored).grok-4.7-build).grok_callwas run live and returned a verdict.grok plugin validate pluginpasses.grok plugin marketplace addplusgrok plugin install tokeneconomizer --trust, which follows grok's docs; I didn't install into a real grok config.hook.mainin the tests.Note for review
This PR and the agy host PR (#147) each add a small
renderseam tohook.runwith different signatures. Whichever lands second needs a small rebase.🤖 Generated with Claude Code