feat(grok): add stream command capturing full SSE response#1848
Draft
Daily-AC wants to merge 1 commit into
Draft
feat(grok): add stream command capturing full SSE response#1848Daily-AC wants to merge 1 commit into
Daily-AC wants to merge 1 commit into
Conversation
`grok ask` polls the DOM for the next assistant bubble, which loses the thinking trace, server-side conversationId/responseId, model id, and generated image URLs that the SSE response carries. `grok stream` adds a single-row command that installs a per-tab `window.fetch` interceptor for `/rest/app-chat/conversations/new`, drains the response stream through `response.clone().body.getReader()` so SSE chunks are captured even while grok.com is also reading the body, and emits one structured row with `response`, `thinking`, `model`, `conversationId`, `responseId`, `title`, and newline-joined `images`. The interceptor is idempotent via a `window.__opencliGrokStreamPatched` guard, falls back to the streamed token concatenation when `modelResponse` is missing, and skips malformed/keep-alive lines so a single bad chunk never drops the whole reply. Unit-tested against a hand-crafted SSE body that mirrors a live capture.
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
Adds
grok stream— captures grok.com'sPOST /rest/app-chat/conversations/newSSE response in full and emits one row withresponse,thinking,model,conversationId,responseId,title, and newline-joinedimages. Companion / motivation: #1847.grok askstays untouched. The new command sits next to it for callers who want the assistant's reasoning trace, server IDs, model id, and generated-image URLs without an extra round-trip through the DOM.How it works
INSTALL_STREAM_INTERCEPTOR_JSonce per tab (idempotent viawindow.__opencliGrokStreamPatched).window.fetch; for any request hitting/rest/app-chat/conversations/newitresponse.clone().body.getReader()-drains the SSE chunks into a buffer, then pushes a{url, method, status, body, capturedAt}envelope ontowindow.__opencliGrokStream.ensureOnGrok/isLoggedIn/startNewChat/sendMessagehelpers fromclis/grok/utils.jsto drive the composer, then polls the queue until the envelope shows up (or--timeoutseconds elapse).summarizeResponsewalks the newline-delimited JSON frames and reduces them: thinking-tagged tokens →thinking, untagged tokens →response, terminalmodelResponsewins over the streamed concatenation,modelResponse.generatedImageUrls→images.Not using
Strategy.INTERCEPT/page.installInterceptor()here because the upstream interceptor callsawait response.clone().json(), which silently drops Grok's newline-delimited JSON. The fetch hook forstreamkeeps the raw body string and parses per site — same approach we'll need for chatgpt/claude/gemini/deepseek SSE shapes in the follow-up PRs.Test plan
npx vitest run clis/grok/stream.test.js— 8 unit tests oniterFrames+summarizeResponseagainst a hand-crafted SSE body (final text, thinking trace, IDs, title, image URL list, malformed-line skipping, empty-body safety)npx tsc --noEmitcleannpm run test:adapter— 380 files / 3722 tests pass with the new file addednpm run build— manifest regenerates, dist/src/main.js exposesopencli grok streamFollow-ups
If this lands cleanly I'll open separate PRs for
chatgpt stream,claude stream,gemini stream,deepseek stream— each parser shape differs enough to deserve its own diff. Detail of each shape is in the issue.