Skip to content

fix(devin): preserve reasoning signature association - #539

Open
luvs01 wants to merge 1 commit into
devfrom
codex/propose-fix-for-invalid-reasoning-signature-pairing
Open

luvs01 wants to merge 1 commit into
devfrom
codex/propose-fix-for-invalid-reasoning-signature-pairing

Conversation

@luvs01

@luvs01 luvs01 commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Motivation

  • The Devin adapter previously concatenated multiple thinking blocks while independently picking the last available signature, which could pair a block's text with a different block's signature and produce an invalid replay to Cognition.

Description

  • Change assistantThinking in src/adapters/devin.ts to select the final non-empty thinking block as a unit and emit its thinking and signature together instead of concatenating all texts and independently choosing a signature.
  • Add a regression test in tests/providers/devin-hardening.test.ts that verifies multiple independently-signed thinking blocks keep the final block's text/signature pair and that an unsigned final block does not inherit a prior signature.
  • Update documentation lines across structure/ docs (adapters/registry.md, data-planes/inbound-compat.md, providers/*, transports/*, runtime.md) to record the adapter's single-pair Devin replay contract and the intended behavior.

Testing

  • Ran bun test tests/providers/devin-hardening.test.ts --timeout 20000 which passed (35 tests, 0 failed).
  • Ran bun run structure:check which passed (structure SSOT checks passed).
  • Ran bun run typecheck which completed successfully.
  • Ran the full suite via bun run test; the run produced many passing tests but also surfaced unrelated environment/shared-state failures (process-group and probe fixtures, forbidden proxy env, and some management-route 403s) that are not caused by this focused change.

Codex Task

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: c90f1fd7-196e-4d2e-9abc-83e72721cf29


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-14T06:26:09.894838Z b69dfbf PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b69dfbfe48

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/adapters/devin.ts
// Only one signature can ride the prompt, so take the last block that has
// one: that is the block the turn actually ended on.
const signature = blocks.filter(b => b.signature).at(-1)?.signature;
const block = blocks.findLast(b => Boolean(b.thinking || b.signature));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Select the last block with reasoning text

When a valid thinking/signature pair is followed by a signature-only block, this predicate selects the latter even though it has no replayable text. Such blocks are valid internal input: src/responses/parser.ts creates them for an envelope containing sig but no plaintext. For a reasoning-only assistant turn, mapOneMessage then drops the entire turn because reasoning.thinking is absent; otherwise it emits an unusable detached signature and loses the earlier valid pair. Search for the last block with non-empty thinking, then carry that same block's signature, as the newly documented contract states.

AGENTS.md reference: src/AGENTS.md:L19-L19

Useful? React with 👍 / 👎.

@github-actions github-actions Bot added the bug Something isn't working label Sep 14, 2026
@github-actions

Copy link
Copy Markdown

Deterministic PR hygiene checks passed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

aardvark bug Something isn't working codex

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant