Repository navigation
Conversation
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
f527616 to
5123fd6
Compare
roboomp
left a comment
There was a problem hiding this comment.
P2 — provider-wide wire/default changes need an explicit maintainer call, and the current patch is not merge-ready.
Blocking: the fallback attestation is shared across every install, explicit generation controls are discarded, and the focused Devin suite fails 2 tests after the raw-frame change.
Also add the required packages/ai Unreleased changelog entry.
Thanks for the detailed capture and comparison, @jroth1111.
1452e3b to
2ec9655
Compare
Align the Devin Connect-RPC adapter's GetChatMessage request with the actual wire format captured from the Devin CLI (v3000.4.25) and Devin Desktop via mitmproxy. The previous adapter impersonated Windsurf and sent fields the CLI never transmits. Key changes verified against captured traffic: - Remove GetUserJwt preflight: place devin-session-token$ directly in Metadata.apiKey (field 3), matching the CLI which performs no JWT exchange. - Fix metadata identity: ideName="devin-cli", extensionName/ideType= "chisel", version="3000.4.25", add os and attestation field 31 (`f`). Remove userJwt, sessionId, requestId, triggerId, lsTimestamp. - Send uncompressed frames (flag 0x00) instead of gzip (flag 0x01), matching the CLI. Remove connect-content-encoding and related headers. - Add authorization header (Basic <token>-<token>) matching the CLI's auth pattern. Suppress Bun's default User-Agent. Set Accept-Encoding to identity to avoid advertising compression the CLI doesn't send. - Fix CompletionConfiguration defaults: maxTokens=128000, maxNewlines= 400, temperature=1.0, topK=40, topP=0.95. All overridable via StreamOptions and model.maxTokens. Remove hardcoded stopPatterns (only caller-specified ones are sent), firstTemperature, fimEotProbThreshold. - Remove extra request fields absent from CLI traffic: executionId, toolChoice, systemPromptCacheOptions, disableParallelToolCalls. - Use getInstallId() for attestation generation instead of hardcoded ID. - Update devin-history.test.ts: decode frames based on Connect flag byte, remove dead GetUserJwt mock, add test asserting authorization header format and User-Agent/Accept-Encoding suppression. - Add packages/ai CHANGELOG entry under [Unreleased]. Note: streamSimple() fills options.maxTokens from model.maxTokens (capped at 64000 by Devin model discovery) before reaching the provider, so the 128000 default only applies when neither the caller nor the model catalog specify maxTokens. This is a pre-existing model discovery issue, not introduced by this PR. Verified via mitmproxy: the patched request's HTTP headers (authorization, content-type, connect-protocol-version, accept), top-level protobuf fields (2, 3, 7, 8, 10, 16, 20, 21), metadata fields (1, 2, 3, 4, 5, 7, 12, 28, 31), and completion config fields (1, 2, 3, 5, 7, 8) are a structural match to the CLI capture. Response frame structure is identical (7 frames). All 17 focused Devin tests pass. The only remaining differences are: - Field 31 (attestation `f`): machine-specific 366-byte blob, different value but same length. Overridable via DEVIN_F_FIELD env var. - topP encoding: CLI uses float32-promoted double (0x3fee666660000000), omp uses native double (0x3fee666666666666) — 1.19e-08 difference. - maxTokens: omp sends 64000 (from model discovery's DEFAULT_MAX_TOKENS cap), CLI sends 128000. Pre-existing issue. - accept-encoding: omp sends identity, CLI sends nothing (HTTP/2). - connection: omp sends keep-alive (HTTP/1.1), CLI uses HTTP/2. - sentry-trace: CLI sends per-request trace IDs (telemetry only). - System prompt content: omp uses its own prompt (expected). Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… parsing Tests cover: - Tool definitions are encoded in GetChatMessageRequest.tools (field 10) - Multiple tool definitions (run_command, edit_file) are encoded correctly - Tool call deltas from response stream are parsed and arguments merged - Multiple tool calls in a single response are parsed correctly Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Lock the CLI wire contract (flag 0x00) in the history capture helper so gzip decode regressions fail loudly. Co-authored-by: Cursor <cursoragent@cursor.com>
…ence Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the stale gzip log field, retarget tool-calling tests at devin-proto imports, and assert frameBytes after CLI-matched uncompressed Connect frames. Co-authored-by: Cursor <cursoragent@cursor.com>
63d0e9f to
c43f5dd
Compare
|
hey my devin provider PR got merged in which refactored provider to be based on devin CLI as opposed to old codeium. looks like you took a look at the desktop app as well, would be curious if there was anything else missing that could go in, but would love to keep the devin support up to date, so let me know if you check this out again to see if any of these still apply so we can get some easy followups for quality of life |
Align the Devin Connect-RPC adapter's GetChatMessage request with the actual wire format captured from the Devin CLI (v3000.4.25) and Devin Desktop via mitmproxy. The previous adapter impersonated Windsurf and sent fields the CLI never transmits. Key changes verified against captured traffic: - Remove GetUserJwt preflight: place devin-session-token$ directly in Metadata.apiKey (field 3), matching the CLI which performs no JWT exchange. - Fix metadata identity: ideName="devin-cli", extensionName/ideType= "chisel", version="3000.4.25", add os and attestation field 31 (`f`). Remove userJwt, sessionId, requestId, triggerId, lsTimestamp. - Send uncompressed frames (flag 0x00) instead of gzip (flag 0x01), matching the CLI. Remove connect-content-encoding and related headers. - Add authorization header (Basic <token>-<token>) matching the CLI's auth pattern. Suppress Bun's default User-Agent. Set Accept-Encoding to identity to avoid advertising compression the CLI doesn't send. - Fix CompletionConfiguration defaults: maxTokens=128000, maxNewlines= 400, temperature=1.0, topK=40, topP=0.95. All overridable via StreamOptions and model.maxTokens. Remove hardcoded stopPatterns (only caller-specified ones are sent), firstTemperature, fimEotProbThreshold. - Remove extra request fields absent from CLI traffic: executionId, toolChoice, systemPromptCacheOptions, disableParallelToolCalls. - Use getInstallId() for attestation generation instead of hardcoded ID. - Update devin-history.test.ts: decode frames based on Connect flag byte, remove dead GetUserJwt mock, add test asserting authorization header format and User-Agent/Accept-Encoding suppression. - Add packages/ai CHANGELOG entry under [Unreleased]. Note: streamSimple() fills options.maxTokens from model.maxTokens (capped at 64000 by Devin model discovery) before reaching the provider, so the 128000 default only applies when neither the caller nor the model catalog specify maxTokens. This is a pre-existing model discovery issue, not introduced by this PR. Verified via mitmproxy: the patched request's HTTP headers (authorization, content-type, connect-protocol-version, accept), top-level protobuf fields (2, 3, 7, 8, 10, 16, 20, 21), metadata fields (1, 2, 3, 4, 5, 7, 12, 28, 31), and completion config fields (1, 2, 3, 5, 7, 8) are a structural match to the CLI capture. Response frame structure is identical (7 frames). All 17 focused Devin tests pass. The only remaining differences are: - Field 31 (attestation `f`): machine-specific 366-byte blob, different value but same length. Overridable via DEVIN_F_FIELD env var. - topP encoding: CLI uses float32-promoted double (0x3fee666660000000), omp uses native double (0x3fee666666666666) — 1.19e-08 difference. - maxTokens: omp sends 64000 (from model discovery's DEFAULT_MAX_TOKENS cap), CLI sends 128000. Pre-existing issue. - accept-encoding: omp sends identity, CLI sends nothing (HTTP/2). - connection: omp sends keep-alive (HTTP/1.1), CLI uses HTTP/2. - sentry-trace: CLI sends per-request trace IDs (telemetry only). - System prompt content: omp uses its own prompt (expected). Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… parsing Tests cover: - Tool definitions are encoded in GetChatMessageRequest.tools (field 10) - Multiple tool definitions (run_command, edit_file) are encoded correctly - Tool call deltas from response stream are parsed and arguments merged - Multiple tool calls in a single response are parsed correctly Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Lock the CLI wire contract (flag 0x00) in the history capture helper so gzip decode regressions fail loudly. Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the stale gzip log field, retarget tool-calling tests at devin-proto imports, and assert frameBytes after CLI-matched uncompressed Connect frames. Co-authored-by: Cursor <cursoragent@cursor.com>
The CLI wire-format alignment entry belonged in [Unreleased], not under the already-released 18.0.9 section. Co-authored-by: Jacob <jroth1111@users.noreply.github.com>
…ider Send uncompressed GetChatMessage frames with Basic auth and identity headers while keeping AssignModel/GetUserJwt from can1357#8590. Move the wire-format changelog entry under Unreleased. Co-authored-by: Jacob <jroth1111@users.noreply.github.com>
Post-can1357#8590 chat is preceded by auth; capture GetChatMessage only and return a JWT response so Connect-frame assertions stay valid. Co-authored-by: Jacob <jroth1111@users.noreply.github.com>
c43f5dd to
184a344
Compare
Rebase onto current main after the Devin CLI provider merge (can1357#8590). Keep AssignModel router, credit metering, and devinCliMetadata identity while applying mitmproxy wire-format fixes: raw Connect frames, Basic auth header, no GetUserJwt preflight, per-install attestation field f, CLI completion defaults, and omission of fields absent from real CLI traffic. Update router tests for uncompressed request decoding and move the packages/ai changelog entry under Unreleased. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Keep local wire-format resolution: no GetUserJwt preflight, raw Connect frames, per-install attestation, and router tests updated for can1357#8590. Co-authored-by: Cursor <cursoragent@cursor.com>
…8534): feat(ai/devin): match Devin CLI wire format from mitmproxy capture
|
Merge update + verification pass (ai typecheck/lint clean). Not superseded: the branch's wire-format delta (raw Connect frames, Basic auth, per-install attestation, CLI completion defaults) remains distinct from upstream's native surface. One judgment call: the header hunk took upstream's user-agent/connect-accept-encoding (CLI 3000.6.2 alignment, newer than this PR's capture) over the older suppress-Bun-identity lines; HTTP accept-encoding stays identity per the capture. All four blocking threads were already fixed on-branch (flag-0x00 decode, install-derived attestation, options-respecting completion defaults, changelog). |
|
Second pass: rebased onto upstream/main, no new review threads. Typecheck clean. |
|
Hey @will-bogusz — yes, re-checked the threads against your merged #8590 surface plus the CLI 3000.6.2 alignment. What remains distinct here: raw Connect frames (flag 0x00), the Basic token-token auth header, per-install attestation field, CLI completion defaults, and no GetUserJwt preflight. I took your newer user-agent/connect-accept-encoding headers over this branch's older suppression lines in the latest merge. The four blocking threads (framing decode, install-derived attestation, options-respecting defaults, changelog) are fixed on-branch. Open to followups if you spot anything else from the desktop capture that's still missing. |
Upstream reworked the provider (GetUserJwt, gzip, stop defaults, Gemini schema normalization); the merge keeps the PR's remaining delta: session- token Basic authorization and the attestation f field.
The capture helpers in devin-history and devin-router read the Connect frame flag byte before decoding, matching devin-tool-calling and the gzip-compressed wire format the provider actually emits. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
What
Align the Devin adapter with the CLI’s authentication and request format, so streaming and tool calls use the expected wire protocol.
fonly when explicitly supplied throughDEVIN_F_FIELD. Do not manufacture it from an install ID or share a fallback value across installations.Why
The request-shape fixes need to coexist with the current Devin adapter, rather than replacing its newer authentication, compression, model routing, and streaming safeguards.
The current head retains
GetUserJwt, gzip Connect request framing, and supported request controls. It does not remove those paths or claim byte-for-byte parity with every CLI request. This supersedes the old description’s raw-frame, generated-device-field, and live-acceptance claims.Testing
Verified published head:
9def97f857552b0ef46428392bdd55d30aa90cf8.bun checkpassed inpackages/ai,packages/catalog, andpackages/coding-agent.The full root
bun checkand workspace Rust tests were not run on this PR head. No fresh live Devin inference was performed. These fixtures do not prove that the service accepts an opaquefvalue or that an account is entitled to a particular backend model.bun checkpasses