Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs-site/src/content/docs/reference/adapters.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,13 @@ Login opens Auth0 browser sign-in, then exchanges the Firebase ID token via
- Experimental unofficial bridge; not shown in the dashboard preset by default. See the
[provider guide](/guides/providers/) for login instructions.

For SWE-2, an explicit reasoning effort overrides an effort suffix in the model
id. For example, `swe-2-high` with `medium` selects the native `swe-2-medium` UID;
`xhigh`, `ultra`, and `max` select `swe-2-max`. Values below Medium select Medium
and do not disable SWE-2 reasoning. Without an explicit effort, a suffixed model
id is preserved. This applies to both Devin account providers through their
shared adapter; other model families keep their existing suffix precedence.

## `devin-cli`

**Targets:** Cognition's `exa.api_server_pb.ApiServerService/GetChatMessage`, the same Connect
Expand Down
14 changes: 12 additions & 2 deletions src/adapters/devin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,23 @@ function hasEffortSuffix(modelId: string): boolean {
* If the catalog is unavailable (degraded mode): append the effort suffix
* for any base id that doesn't already carry one, mirroring the catalog shape.
*/
async function resolveWireModelUid(
export async function resolveWireModelUid(
rawModelId: string,
apiKey: string,
host: string,
reasoningEffort?: string,
): Promise<string> {
const modelId = normalizeDevinModelId(rawModelId);
let modelId = normalizeDevinModelId(rawModelId);
// SWE-2's native UIDs encode the effort. A suffix on a picker model must
// not silently discard the caller's explicit reasoning selection.
if (/^swe-2(?:-(?:medium|high|max))?$/.test(modelId)) {
const efforts: Record<string, string> = {
none: "medium", off: "medium", minimal: "medium", low: "medium",
medium: "medium", high: "high", xhigh: "max", ultra: "max", max: "max",
};
const effort = reasoningEffort ? efforts[reasoningEffort] : undefined;
if (effort) modelId = `swe-2-${effort}`;
}
if (hasEffortSuffix(modelId)) return modelId;
const catalog = await getCachedCatalog(apiKey, host);
if (catalog) {
Expand Down
7 changes: 7 additions & 0 deletions structure/adapters/registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,10 @@ see [Combo editor routing quota](../gui-and-management-api.md#combo-editor-routi
Claude replay carries [Go conversation affinity](../data-planes/inbound-compat.md#claude-affinity-at-final-go-dispatch)
privately to final dispatch; preliminary route selection does not inject Go-only headers.
Native Chat applies qualifying effort ceilings independently of model pins; pin selection precedes the cap and only pins or cap rewrites enter wire mapping. The [catalog effort contract](../catalog.md#ultra-reasoning-level) records the V1/compaction exemptions and caller-preservation boundary.

## SWE-2 model effort selection

`src/adapters/devin.ts` resolves an explicit SWE-2 reasoning effort to the native
medium/high/max UID before accepting a suffix already present in the model id.
Both Devin provider rows share this resolver. Omitted effort preserves an explicit
variant; unrelated model families retain their existing suffix precedence.
2 changes: 2 additions & 0 deletions structure/data-planes/inbound-compat.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,5 @@ Instruction notice extraction scans fence ranges once and walks original lines b
a decreasing cursor. It accepts exactly one ASCII space inside the token notice, preserves
unmatched prefix bytes, and does not repeatedly scan or copy shrinking prompt prefixes.
Native Chat applies qualifying effort ceilings independently of model pins; pin selection precedes the cap and only pins or cap rewrites enter wire mapping. The [catalog effort contract](../catalog.md#ultra-reasoning-level) records the V1/compaction exemptions and caller-preservation boundary.

The shared Devin adapter owns [SWE-2 model effort selection](../adapters/registry.md#swe-2-model-effort-selection); this UID rewrite is not a shared routing rule for other models.
2 changes: 2 additions & 0 deletions structure/providers/chat-compat.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,5 @@ fragments are not guessed onto pending ID-only calls.
parallel/colliding identities, distinct unsafe raw JSON index literals, the maximum
safe-integer boundary, invalid index types, missing/null continuations and UTF-8
byte-limit boundaries.

The shared Devin adapter owns [SWE-2 model effort selection](../adapters/registry.md#swe-2-model-effort-selection); this UID rewrite is not a shared routing rule for other models.
2 changes: 2 additions & 0 deletions structure/providers/cursor.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,5 @@ constraints cannot widen the canonical shape. Bare shell bridge names are reject
on the freeform path.
Namespaced tools do not acquire bare-shell behavior. Regression coverage lives in
`tests/providers/cursor/cursor-tool-definitions.test.ts`.

The shared Devin adapter owns [SWE-2 model effort selection](../adapters/registry.md#swe-2-model-effort-selection); this UID rewrite is not a shared routing rule for other models.
2 changes: 2 additions & 0 deletions structure/runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,5 @@ The lightweight top-level CLI help counts Cline CLI among the fifteen registered
Devin CLI credential path composition in `src/oauth/devin-cli.ts` follows the selected platform: Windows uses Win32 APPDATA paths, other platforms use POSIX XDG-data paths. The explicit absolute override remains verbatim; credential parsing and login behavior are unchanged.

Native Chat applies qualifying effort ceilings independently of model pins; pin selection precedes the cap and only pins or cap rewrites enter wire mapping. The [catalog effort contract](catalog.md#ultra-reasoning-level) records the V1/compaction exemptions and caller-preservation boundary.

The shared Devin adapter owns [SWE-2 model effort selection](adapters/registry.md#swe-2-model-effort-selection); this UID rewrite is not a shared routing rule for other models.
2 changes: 2 additions & 0 deletions structure/transports/inventory.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,5 @@ privately to final dispatch; preliminary route selection does not inject Go-only
Devin CLI credential path composition in `src/oauth/devin-cli.ts` follows the selected platform: Windows uses Win32 APPDATA paths, other platforms use POSIX XDG-data paths. The explicit absolute override remains verbatim; credential parsing and login behavior are unchanged.

Native Chat applies qualifying effort ceilings independently of model pins; pin selection precedes the cap and only pins or cap rewrites enter wire mapping. The [catalog effort contract](../catalog.md#ultra-reasoning-level) records the V1/compaction exemptions and caller-preservation boundary.

The shared Devin adapter owns [SWE-2 model effort selection](../adapters/registry.md#swe-2-model-effort-selection); this UID rewrite is not a shared routing rule for other models.
2 changes: 2 additions & 0 deletions structure/transports/responses.md
Original file line number Diff line number Diff line change
Expand Up @@ -524,3 +524,5 @@ see [Combo editor routing quota](../gui-and-management-api.md#combo-editor-routi
Claude replay carries [Go conversation affinity](../data-planes/inbound-compat.md#claude-affinity-at-final-go-dispatch)
privately to final dispatch; preliminary route selection does not inject Go-only headers.
Native Chat applies qualifying effort ceilings independently of model pins; pin selection precedes the cap and only pins or cap rewrites enter wire mapping. The [catalog effort contract](../catalog.md#ultra-reasoning-level) records the V1/compaction exemptions and caller-preservation boundary.

The shared Devin adapter owns [SWE-2 model effort selection](../adapters/registry.md#swe-2-model-effort-selection); this UID rewrite is not a shared routing rule for other models.
28 changes: 27 additions & 1 deletion tests/providers/devin-adapter.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, test } from "bun:test";
import { createDevinAdapter, mapOcxMessagesToDevin, mapOcxToolsToDevin } from "../../src/adapters/devin";
import { createDevinAdapter, mapOcxMessagesToDevin, mapOcxToolsToDevin, resolveWireModelUid } from "../../src/adapters/devin";
import { sanitizeToolDescriptionForCognitionForTests } from "../../src/adapters/devin/cloud-direct/chat";
import { DEVIN_MODEL_CONTEXT_WINDOWS, DEVIN_STATIC_MODELS, collapseDevinModelUid } from "../../src/adapters/devin/live-models";
import { parseCatalogBuffer } from "../../src/adapters/devin/cloud-direct/catalog";
Expand Down Expand Up @@ -201,3 +201,29 @@ describe("devin adapter", () => {
}
});
});

describe("SWE-2 wire effort selection", () => {
test.each(["medium", "high", "max"])("an explicit %s effort overrides every SWE-2 variant", async (effort) => {
for (const model of ["swe-2", "swe-2-medium", "swe-2-high", "swe-2-max", "swe-2.high"]) {
expect(await resolveWireModelUid(model, "unused", "unused", effort)).toBe(`swe-2-${effort}`);
}
});

test.each([
["none", "medium"], ["off", "medium"], ["minimal", "medium"],
["low", "medium"], ["xhigh", "max"], ["ultra", "max"],
])("maps %s to the supported SWE-2 %s lane", async (effort, expected) => {
expect(await resolveWireModelUid("swe-2-high", "unused", "unused", effort)).toBe(`swe-2-${expected}`);
});

test("omitted or unknown effort preserves an explicit variant", async () => {
expect(await resolveWireModelUid("swe-2-high", "unused", "unused")).toBe("swe-2-high");
expect(await resolveWireModelUid("swe-2-max", "unused", "unused", "future-effort")).toBe("swe-2-max");
});

test("other model families keep their existing suffix precedence", async () => {
for (const model of ["claude-opus-5-medium", "gpt-5-6-sol-high", "swe-1-7-high", "swe-20-high"]) {
expect(await resolveWireModelUid(model, "unused", "unused", "max")).toBe(model);
}
});
});
Loading