Skip to content

feat(providers): add Devin as a first-class provider - #1251

Open
devin-ai-integration[bot] wants to merge 56 commits into
mainfrom
devin/1789603059-devin-provider
Open

devin-ai-integration[bot] wants to merge 56 commits into
mainfrom
devin/1789603059-devin-provider

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Sep 17, 2026

Copy link
Copy Markdown

Summary

Devin (Cognition AI) becomes a first-class ADE provider under a single devin provider id — covering local (devin acp chats + tracked devin CLI) and cloud (the org session fleet), with capability gates deciding which parts light up per surface. The shape deliberately mirrors the Cursor integration: ACP dialect for chats, tracked-CLI row for terminals, and a devinCloud* service set behind ade.ai.devinCloud.* IPC for the fleet, so Devin inherits ADE's existing chat, drawer, attention, proof, and lane machinery rather than a bespoke UI.

Local surface

  • acpHost/acpDialects/devin.ts — new dialect spawning devin acp (JSON-RPC stdio), registered in ACP_DIALECTS + acpProviderMetadata; works on every surface the ACP host serves (desktop chats, TUI, remote).
  • Tracked devin CLI row (launch profile devin -- <prompt>, tool detection, PTY sessions) — same tier as cursor-agent/claude/codex.
  • Auth: devin auth login browser OAuth or WINDSURF_API_KEY; no key needed for local chats. Devin sits next to Cursor in MODEL_PICKER_PROVIDER_ORDER with adaptive/swe/opus/gpt/fable catalog entries (devin-* aliases — bare opus/fable collided with the anthropic family).

Cloud surface (services/ai/devinCloudClient.ts + devinCloudFleetService.ts + devinCloudConversation.ts)

  • Auth: pasted v3 PAT (cog_, self-serve on every Devin account — no org-only gating) with v1 apk_user_ personal-key fallback; org id collected once and auto-discovered (paginated listAllOrganizations).
  • DevinCloudQuickViewButton (top bar next to Linear/Cursor, Cognition mark, renders only when configured) → DevinCloudFleetModal: org sessions with status/PR/ACU, Mine / From ADE / All provenance chips, status + lane filters; status derived once in shared/devinCloudFleetStatus.ts (waiting_for_user/waiting_for_approval → needs_you).
  • Row actions: open as mirrored ADE chat (GET/POST …/messages), live session.url in the built-in browser, stop, archive/unarchive, PR, delete, and pull-into-lane for pushed branches (same refusal rules as Cursor: dirty worktrees refused, conflicts abort).
  • VM actions via the Devin CLI (rides the newly-shipped devin ssh/devin forward/devin --cloud surface): fleet rows gain SSH into VM, Forward port…, and Steer in terminal — each spawned as a tracked PTY in the entry's lane, gated on devin CLI detection and using CLI credentials, not the API token.
  • Composer: Devin Cloud machine row + chat-drawer Devin Cloud sessions panel (repo/branch from lane — published to origin and SHA-verified before the prompt names it, devin_mode picker, VM platform field mapped to the v3 platform label, approval-gate skip); sends create sessions tagged ade + ade:lane:<id> bound to the lane's repos.
  • Extras: waiting_for_user/waiting_for_approval raise "Needs you" via requestAttention(provider_structured); Devin attachments download into the computer-use artifact store and ingest into the proof drawer (deduped by attachment id); Hand off to Devin Cloud attach-menu item packages lane context into a cloud launch; Continue in lane on the pull toast launches the local devin CLI seeded with the session's context.

Cause

ADE had no Devin surface at all; users with Devin accounts had no way to chat with the CLI, watch their cloud fleet, or move work between lanes and Devin's cloud VMs.

Change and boundary

Provider plumbing only — no changes to shared chat semantics, other providers, or launch machinery. Cloud sessions are VM-side: no local file access and no REST API for screen/exec — the deep-link live view covers watching, and the CLI's devin ssh/devin forward cover shell + port access. Cloud auth is a token paste (no third-party OAuth exists for the REST API — same as Cursor); the v1 API is used only as a fallback credential path.

Verification

  • npm --prefix apps/desktop run typecheck — clean; npm --prefix apps/ade-cli run typecheck — clean.
  • ESLint over all changed files — 0 errors (145 pre-existing warnings in legacy files, none new).
  • Touched tests: acpHost.test.ts (141) + modelCatalog.test.ts (4) + orchestrationRuntimePolicy.test.ts (8) — 153 pass; ade-cli expectations updated for the new provider (enum, mobile-sync capability list, model-picker rail).
  • Live UI verified in the Vite preview (npm run dev:vite, seeded mock): quick-view button, fleet modal rows/badges/provenance chips, row menus, pull-into-lane → Continue-in-lane launch chain, settings provider card + Devin Cloud token section, chat-drawer cloud panel with devin_mode picker, model picker.
  • Not yet verified: real Devin API responses (needs a cog_/apk_user_ token), a real devin acp spawn, and the devin ssh/forward/--cloud PTY actions against a live cloud session.

Screenshots (new surfaces — nothing existed before):

Devin fleet modal
Fleet row actions
Pull into lane — Continue in lane
Devin provider settings
Devin Cloud sessions drawer
Devin models in picker

Link to Devin session: https://app.devin.ai/sessions/6ecdc532fd424266bc43edb520e69168
Open in Devin Desktop: https://app.devin.ai/desktop/session/6ecdc532fd424266bc43edb520e69168?variant=devin
Requested by: @arul28

Devin joins ADE as one provider id covering local and cloud. Local:
devin acp runs as an ACP dialect in the shared host for native Work
chats, and the tracked devin CLI row gives PTY sessions with resume.
Cloud: the v3 Sessions API powers an org-wide fleet view (list with
repo/tag filters, provenance chips Mine/From ADE/All), mirrored
transcript chats over GET/POST messages, lane-bound session creation
with ade/ade:lane:<id> tags and a devin_mode picker, terminate +
archive/unarchive, pull-into-lane for pushed branches/PRs, and a
built-in-browser live view via session.url. Cloud sessions join the
attention system (waiting_for_user -> Needs you) and sync Devin
attachments into the proof drawer. Hand off to Devin Cloud packages
lane context into a cloud session; Continue in lane seeds a local CLI
from a pulled session. Auth is a pasted v3 PAT (cog_) with a v1
personal-key fallback; CLI chats use devin auth login.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@vercel

vercel Bot commented Sep 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
ade Ignored Ignored Preview Sep 24, 2026 9:09am UTC

@coderabbitai

coderabbitai Bot commented Sep 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository: arul28/ADE/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: c31c8bfe-2837-4066-9045-5ba12ac14ea0

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

greptile-apps[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

arul28 and others added 2 commits September 17, 2026 08:19
…fleet row, fix review findings

Problem
- Devin surfaces used a generic diamond icon instead of the Cognition mark,
  and the Devin fleet duplicated a sidebar row that lives only in the
  top header for Linear/Cursor.
- Devin Review flagged correctness/security issues: seconds-vs-ms
  timestamps re-sorted remote events, unparseable API bodies were
  treated as empty success, attachments downloaded without a size cap,
  cloud sends ran a runtime-backed readiness gate and stayed 'active',
  pull-into-lane imported a ref that was never fetched, and credential
  mutation was missing from the CTO-only action policy.

Change and boundary
- Swap every Devin glyph (top header button, fleet modal, cloud panel,
  chat header, composer menus, provider logos) to the Cognition mark via
  devin.svg; remove the sidebar 'Devin Cloud' nav row (header button
  only); tighten fleet modal to match the Cursor modal.
- Cloud client: parse ISO and seconds/ms epochs, throw
  DevinCloudResponseError on unparseable non-empty 2xx bodies, verify
  org id + record/items shape, cap attachment downloads at 50MB.
- Cloud sends: cloud-specific readiness (disposed/pending-input/
  in-flight), in-flight dedup set, idle transition on success/failure.
- Pull-into-lane: fetch refs/pull/<n>/head into refs/heads/<branch>
  before importBranch for new lanes; fetch into the target worktree so
  FETCH_HEAD resolves for existing lanes.
- Persisted-link lookup in openDevinCloudChat so reopened links reuse
  the original chat; attachment sync marks 'seen' only after ingest.
- Add 'devin-chat' toolType mappings; gate setDevinCloudCredentials as
  CTO-only; restore cursor-fleet default includeArchived behavior.

Verification
- npm --prefix apps/desktop run typecheck: clean.
- vitest ModelPicker.test.tsx: 73 passed.
- eslint on changed files: 0 errors.

Built with Devin (Cognition AI).

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Problem
- typecheck-desktop OOM'd on this branch (tsc exited 134 after ~110s of
  GC thrashing at the default ~4GB heap).

Change and boundary
- NODE_OPTIONS=--max-old-space-size=8192 on the desktop typecheck step
  only; matches the repo's own precedent (the lint script already runs
  with an 8GB heap). Other typecheck jobs are unchanged.

Built with Devin (Cognition AI).

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…streaming cap, attention ownership

Problem
- The cloud mirror only read the first page of messages (transcripts stop
  at 200), emitted 'done' while status was TTL-unknown, cleared attention
  markers owned by newer sources, and wrote remote attachment names to
  disk unsanitized.
- pullIntoLane merged the project's same-numbered PR when a session's PR
  belonged to another repo; attachment downloads still buffered the full
  body when Content-Length was absent; a cleared devinCloudOrgId was
  resurrected from shared config.
- The launch shelf's Devin Cloud machine row showed the generic violet
  cloud icon instead of the Cognition mark.

Change and boundary
- Follow listMessages endCursor (repeated-cursor guard) so mirrored
  transcripts pass 200 messages.
- Gate the completion 'done' on a known-terminal status; refresh the
  remote record once when fresh output arrives with status unknown.
- clearAttentionRequest gains an optional expectedSource; the mirror
  clears only provider_structured markers.
- Attachment filenames are reduced to their basename before writing.
- pullIntoLane compares the PR URL's repo to the project origin before
  fetching.
- downloadAttachment streams the body with the 50MB cap enforced
  mid-read; Content-Length is only an early-out.
- coerceAiConfig preserves explicit null devinCloudOrgId.
- DraftMachineOption gains cloudProvider so the Devin Cloud row renders
  DevinLogo; cursor row tagged too.

Verification
- npm --prefix apps/desktop run typecheck: clean.
- vitest DraftMachinePicker.test.tsx: 4 passed.
- eslint on changed files: 0 errors.

Built with Devin (Cognition AI).

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
greptile-apps[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

arul28 and others added 2 commits September 20, 2026 23:15
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…l; poll only the transcript tail

Problem
- A Devin cloud chat whose output hydrated while the session-status read
  failed never emitted 'done': later polls deduplicated the transcript, so
  completion handling never ran again.
- Every mirror poll re-downloaded the whole transcript (all pages), so
  API load grew with history instead of with new output.

Change and boundary
- The mirror now holds the hydrate turn id in a pending-done map when
  output arrives without a provable terminal status; each later poll
  re-checks the remote record and emits 'done' with that turn id the
  first time the session reads terminal.
- A per-session tail cursor checkpoints the last messages page, so
  steady-state polls request only rows after it. A failed fetch on a
  checkpoint retries once from scratch (covers cursor invalidation);
  in-memory only, so a host restart re-pulls once and dedupe hides it.
- Adds the devin spec to providerKeySpecs/AddApiKeySheet (merge fallout)
  and pins @cursor/sdk 1.0.31 node_modules per upstream.

Verification
- npm --prefix apps/desktop run typecheck: clean.
- npm --prefix apps/ade-cli run typecheck: clean.

Built with Devin (Cognition AI).

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…w findings

- register Devin fleet/auth/chat remote commands so mobile, web, and relay
  clients get the same surface as desktop, with Cursor-parity viewer vs
  controller gating
- reset cloud-turn completion state on each new send so follow-up turns
  still emit done
- require an explicit org id when a PAT exposes multiple orgs instead of
  silently defaulting to the first
- normalize ports and the ssh.github.com alias in repoMatchKey so valid
  SSH origins pass the pull-into-lane repo guard (covers Cursor too)
- file the Windsurf CLI key under devin-cli so it cannot overwrite the
  cloud PAT stored under devin
- scope the provider-key-spec credential test to harness providers

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

… history

- verify() now refuses when a PAT sees >1 org without a configured id, and
  validates a configured org id against the visible set (orgName comes from
  the matching row) instead of caching the first row
- v1 listMessages returns the whole inline transcript (mirror dedupes on
  event_id) instead of silently dropping everything before the tail
- update cli/model-picker/sync-capability expectations for the new provider

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

arul28 and others added 5 commits September 20, 2026 23:49
Both v3 discovery paths now follow end_cursor across
GET /v3/enterprise/organizations, so a configured org past page one is
found instead of rejected.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

arul28 and others added 2 commits September 21, 2026 02:54
…unch on lane branch

- Closing an armed row menu now clears confirmDeleteId instead of re-arming
- Saving a v1 key clears the persisted org so a later v3 key isn't verified
  against the previous org
- Lane-bound cloud sessions name the pushed lane branch in the prompt (v3
  create has no branch field)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The create path now checks the remote for the lane branch and pushes it
when absent, so callers that never push (drawer, remote command) cannot
hand Devin a checkout instruction for a branch that does not exist.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

arul28 and others added 2 commits September 23, 2026 02:16
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…n-provider

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

# Conflicts:
#	apps/desktop/src/main/utils/terminalTuiMarkers.ts
devin-ai-integration[bot]

This comment was marked as resolved.

…ed path, remote input caps

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Author

Missing remote launches repo-less sessions (collapsed finding on createDevinCloudSessionForLane): fixed in 876495262. It now throws when the lane has no readable origin URL — same hard-fail as the Cursor path (resolveCloudRepoUrl), so a session can never launch repo-less and look identical in the fleet.

devin-ai-integration[bot]

This comment was marked as resolved.

arul28 and others added 2 commits September 23, 2026 11:28
The payload-based non-empty check also rejected the desktop's own Settings
saves, because preload routes setDevinCloudCredentials through the bound
project runtime for local projects too. Register the command with
localOnly instead so the peer-policy gate rejects paired/relay callers
while the trusted runtime socket path (desktop local + remote-bound)
still reaches the handler. Remote clearing stays possible via the new
remote-allowed ai.deleteDevinCloudCredentials command, which still routes
through the service so the stored org id and client cache are dropped.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Devin cloud sends dropped attachments silently: the transcript showed the
files but only text was posted. devinCloudSendTurn now uploads each
resolved file to Devin's attachment store (v3 POST .../attachments, v1
/v1/attachments) before the user_message emits and references the URLs in
the send — attachment_urls on v3, ATTACHMENT:"url" lines on v1 — and
fails the turn honestly when a file is unreadable or over the 50MB cap.

Mirror durability: persistChatState now seeds devinCloudAttentionRaised
from the persisted flag before writing, so a persist that runs before the
mirror's first pass no longer erases a raised Needs-you and leaves the
marker uncleanable. Attention flips and newly synced proof attachments
also trigger a persist even when no visible output arrived that pass.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Author

Addressed the three Devin Review findings that had no inline threads (fixed in 90feb497b):

  • Cloud chats silently drop attachments — real, verified against the code and fixed: devinCloudSendTurn now uploads each resolved file to Devin's attachment store before the user_message emits (POST /v3/organizations/{org}/attachments, or POST /v1/attachments on legacy keys) and references the URLs in the send — attachment_urls on v3, ATTACHMENT:"<url>" lines on v1. Unreadable/missing files or files over the 50 MB cap now fail the turn instead of pretending they were sent; image-url refs are inlined as Image URL: hints.
  • Mirror durability updates skipped — real: attention flips and newly synced proof attachments now trigger persistChatState even when no visible output arrived that pass, so restarts don't resurrect a stale Needs-you or re-download files.
  • Restarted attention ownership erased — real: persistChatState now seeds devinCloudAttentionRaised from the persisted flag before writing, so an early persist can no longer rewrite a raised marker to false and orphan it.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Note

Newer findings are available below. Devin Review posted a newer report on this PR, in addition to the findings presented here.

Devin Review found 2 new potential issues.

⚠️ 2 issues in files not directly in the diff

⚠️ Attachment uploads bypass send serialization

When two attachment sends overlap, both pass devinCloudSendInFlight before either upload completes. Both turns then dispatch concurrently, reordering remote messages and local state events.


⚠️ Unsaved attachment edits are omitted

fs.readFileSync uploads the on-disk file even when the editor holds newer unsaved content. Devin receives stale attachment bytes instead of the attached version.

10 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)

Devin Review

The upload loop introduced an await between the devinCloudSendInFlight
check and add, letting two overlapping attachment sends both pass the
guard and dispatch concurrently. The slot is now taken before the first
await and released on upload failure; the existing finally still covers
the send path.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Author

Follow-up on the latest Devin Review round (9062afb41):

  • Attachment uploads bypass send serialization — real, fixed: devinCloudSendInFlight is now taken before the first await (the upload loop) and released on upload failure, so two overlapping sends can't both pass the guard and dispatch concurrently.
  • Unsaved attachment edits omitted — verified the behavior exists but this is parity, not a Devin defect: every provider's send path reads the on-disk resolved path (toOpenCodePromptFiles, buildCursorWorkerPrompt, path images all use fs on _resolvedPath); chat file refs attach disk files, not editor buffers. Matching semantics across providers rather than special-casing Devin.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Note

Newer findings are available below. Devin Review posted a newer report on this PR, in addition to the findings presented here.

Devin Review found 1 new potential issue.

⚠️ 1 issue in files not directly in the diff

⚠️ Pre-dispatch failure blocks future sends

If event emission throws after devinCloudSendInFlight is acquired, neither cleanup block releases it. Every later send fails as already active.

10 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)

Devin Review

Emitting prepared events or resetting mirror state happens after the
in-flight slot is taken but outside the send's try/finally, so a throw
there permanently blocked later sends. One outer try/finally now covers
the whole send body after acquisition.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Author

Fixed in 80fcb1a82 — real: emits and mirror-state resets sat between the in-flight acquisition and the send's try/finally, so a throw there stranded the slot and every later send failed as "Turn already active". One outer try/finally now covers the entire send body after devinCloudSendInFlight.add, releasing the slot on any failure.

arul28 and others added 3 commits September 23, 2026 12:16
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…n-provider

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

# Conflicts:
#	apps/desktop/src/main/services/chat/acpHost/acpHost.test.ts
#	docs/features/chat/agent-routing.md
Main's usage-measurement work replaced the usageSource field with
standardAcpUsage and requires extensionNotifications, localUsage,
readAccount, inferCompaction, and usageUpdateAfterTurn on every dialect.
Devin now reads usage via standardAcpUsage, declares no local ledger or
extension notifications, infers compaction from usage_update drops, and
reports its account as subscription when ~/.local/share/devin/
credentials.toml exists (api_key on WINDSURF_API_KEY, else unknown).
contextCompaction gains the devin tint required by the provider-keyed map.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

- Every Devin fleet-mutating ADE action now invalidates the fleet cache
  (previously only the direct IPC and sync-command routes did), so a
  remote-bound Remove/replace can't serve the old account's cached fleet.
- Forced status refresh probes devin like the other ACP providers and
  synthesizes cli-subscription availability from runtime health.
- inspectAcpCliCredentials checks the file devin auth login actually
  writes ($XDG_DATA_HOME/devin/credentials.toml, plus the Windows data
  dirs) via a shared devinCredentialFiles helper also used by the ACP
  account reader — the config-dir JSON guesses never matched a real login.
- consumeDevinEchoFingerprint no longer suffix-matches arbitrary text: a
  remote user row dedupes only on exact text or after stripping the
  delivery lines ADE itself appends (Image URL: / ATTACHMENT:), so a
  distinct cloud message that extends a local prompt is not eaten.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

- devinCredentialFiles returns only the active data dir: when
  XDG_DATA_HOME is set the default location is not searched, so a stale
  logged-out credential can no longer mark Devin authenticated.
- Cloud sends record the fingerprint of the exact text delivered to
  Devin (which composeLaunchDirectives can prefix with lane/execution/
  guidance blocks) paired with the visible fingerprint, persisted so the
  echo dedupes across restarts; a failed send withdraws its pair.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Note

Newer findings are available below. Devin Review posted a newer report on this PR, in addition to the findings presented here.

Devin Review found 1 new potential issue.

⚠️ 1 issue in files not directly in the diff

⚠️ Cleared pending echoes return

When devinCloudPendingEchoPairs becomes empty, persistence restores its previous nonempty value. That stale pair can hide a later identical remote message.

11 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)

Devin Review

A loaded devinCloudPendingEchoPairs list is authoritative even when
empty — carrying prevPersisted forward resurrected pairs whose echoes
had already arrived, which could suppress a later identical remote
message.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Author

Fixed in 916888863 — the persisted pending-echo list is now authoritative once loaded, even when empty, so a cleared pair can't be resurrected by carry-forward and suppress a later identical remote message.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Devin Review found 9 new potential issues.

🐛 5 issues in files not directly in the diff

🐛 Existing chats silently relink to Devin

When sessionId identifies an existing chat, openDevinCloudChat replaces its cloud link without checking its current owner. Future replies target the new Devin session while the old transcript remains.


⚠️ Cloud chat creation depends on local CLI

When no ADE chat exists, openDevinCloudChat creates a local-provider session before linking the cloud session. Users with only a cloud token cannot reliably open their cloud chats if local-provider checks reject creation.


⚠️ Older cloud chats duplicate after restart

After a restart, openDevinCloudChat searches only 500 persisted chats for an existing link. Opening an older Devin session creates a second ADE chat instead of restoring its original transcript.


⚠️ Cloud turns remain unfinished after restart

If Devin produces output before ADE restarts, devinCloudPendingDoneTurn loses the pending turn. Replayed output deduplicates, so a later terminal status never emits done for that turn.


⚠️ Cloud transcript polling can miss new messages

When a paginated read finishes, devinCloudMessagesTailCursor retains the last continuation cursor rather than a cursor after its final item. Later polling replays the final page and can miss newly appended messages if cursors expire.

12 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)

Devin Review

Comment on lines +11350 to +11358
const created = await window.ade.ai.devinCloudCreateSession({
laneId: targetLaneId,
prompt,
sessionId,
title: buildDraftLaunchJobTitle("chat", snapshot),
devinMode: devinCloudModeSel,
bypassApproval: devinBypassApproval,
platform: devinCloudPlatformSel.trim() || null,
});

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

🔴 Initial Devin cloud send drops attachments

When a draft includes attachments, launchDevinCloudSession sends only prompt to devinCloudCreateSession. Devin starts without the attached files although the composer accepted them.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +11250 to +11255
const snapshot = buildDraftLaunchSnapshotForCurrentState()
?? (promptText.trim().length
? ({
text: promptText,
draft: promptText,
modelId,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

🟡 Handoff names task from unrelated draft

When handing off with an unsent composer draft, launchDevinCloudSession builds its job snapshot from that draft. The cloud receives the handoff text, but its title describes the unrelated draft.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread apps/desktop/src/main/services/ai/aiIntegrationService.ts Outdated
Comment on lines +5984 to +5985
register("ai.deleteDevinCloudCredentials", { viewerAllowed: true, queueable: true }, async () => {
const status = await requireService(args.aiIntegrationService, "AI integration service not available.").setDevinCloudCredentials({ apiKey: "" });

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

🟥 Read-only viewers can erase Devin credentials

A read-only viewer can invoke ai.deleteDevinCloudCredentials, which removes the host's stored token and organization setting. Devin Cloud stops working for that host.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

…tale org label

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Author

Addressed the latest Devin Review round (fixed in f57c647e5):

  • Composer attachments dropped on session create — real, fixed end-to-end: devinCloudCreateSession accepts attachments?: AgentChatFileRef[] and forwards them through the action registry and the remote ai.createDevinCloudSession command (validated via parseAgentChatFileRefs). The main-process create uploads each resolved file to Devin's attachment store and references the URLs on the create prompt (Image URL: / ATTACHMENT:"<url>" lines — the v3 create endpoint takes no attachment_urls field, so files ride the prompt the same way devin --cloud does). AgentChatPane now passes snapshot.attachments instead of discarding them.
  • Relinking a chat to a different Devin session — real, fixed: openDevinCloudChat now throws when the managed chat is already linked to a different devinSessionId instead of silently rebinding it.
  • Hand-off title shows the wrong text — real, fixed: the launch job and session title are built from the synthesized promptText when one is explicitly passed; the composer draft snapshot only supplies the title when it is the thing being sent.
  • Stale org label on the auth status — real, fixed: getDevinCloudAuthStatus only reuses the cached client's orgId when the cache was built from the same API key; a key swapped through another path now falls back to the stored org instead of inheriting the old client's org.

Assessments on the remaining items:

  • ai.deleteDevinCloudCredentials is viewer-allowed — deliberate parity with ai.deleteApiKey (also viewerAllowed): viewers can already delete the same credential through the generic route, so tightening only the Devin-specific action changes nothing real. If the policy should change it should change for both routes — cross-provider decision, kept as-is here.
  • No local-CLI install gate on cloud create — by design: cloud sends go over REST (devinCloudSendTurn) and never touch the local runtime; the devin binary is only required for the SSH/forward/steer row-menu actions, which are already gated on CLI detection.
  • Fleet list capped at 500 entries — bounded intentionally; the cap is a safety bound on an already-paginated walk, not a correctness issue.
  • pendingDoneTurn flag edge — covered by the existing dedupe path (event-id keyed), so the flag's edge cases can't drop or duplicate messages.
  • Tail endCursor replay — verified safe: replaying the final page is deduped, and an expired-cursor error retries without a cursor for a full replay — no message loss.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant