Send Devin Desktop Windsurf version instead of CLI build id.
This commit is contained in:
+3
-1
@@ -3,6 +3,7 @@ import type { Api, Model, OAuthCredentials, OAuthLoginCallbacks } from "@earendi
|
|||||||
import { authStatus, loginWithCli, readCredentials } from "../src/credentials.js";
|
import { authStatus, loginWithCli, readCredentials } from "../src/credentials.js";
|
||||||
import { whichDevin, devinVersion } from "../src/cli.js";
|
import { whichDevin, devinVersion } from "../src/cli.js";
|
||||||
import { FALLBACK_MODELS, loadCliCatalog, modelsFromCatalog } from "../src/models.js";
|
import { FALLBACK_MODELS, loadCliCatalog, modelsFromCatalog } from "../src/models.js";
|
||||||
|
import { CLIENT_IDE, CLIENT_VERSION } from "../src/metadata.js";
|
||||||
import { streamDevin } from "../src/stream.js";
|
import { streamDevin } from "../src/stream.js";
|
||||||
|
|
||||||
const PROVIDER_ID = "devin";
|
const PROVIDER_ID = "devin";
|
||||||
@@ -86,7 +87,8 @@ export default async function (pi: ExtensionAPI): Promise<void> {
|
|||||||
ctx.ui.notify(
|
ctx.ui.notify(
|
||||||
[
|
[
|
||||||
bin ? `CLI: ${bin}` : "CLI: not found",
|
bin ? `CLI: ${bin}` : "CLI: not found",
|
||||||
version ? `Version: ${version}` : "Version: unknown",
|
version ? `CLI version: ${version}` : "CLI version: unknown",
|
||||||
|
`Client identity: ${CLIENT_IDE} ${CLIENT_VERSION}`,
|
||||||
status.loggedIn ? "Auth: signed in via Devin CLI" : "Auth: not signed in. Run /login devin or `devin auth login`",
|
status.loggedIn ? "Auth: signed in via Devin CLI" : "Auth: not signed in. Run /login devin or `devin auth login`",
|
||||||
].join("\n"),
|
].join("\n"),
|
||||||
status.loggedIn && bin ? "info" : "warning",
|
status.loggedIn && bin ? "info" : "warning",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "pi-devin",
|
"name": "pi-devin",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"description": "Pi provider for Devin Local models. Auth and catalog come from the local Devin CLI; Pi stays the harness.",
|
"description": "Pi provider for Devin Local models. Auth and catalog come from the local Devin CLI; Pi stays the harness.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
+31
-5
@@ -1,3 +1,4 @@
|
|||||||
|
import { existsSync, readFileSync } from "node:fs";
|
||||||
import {
|
import {
|
||||||
encodeMessage,
|
encodeMessage,
|
||||||
encodeString,
|
encodeString,
|
||||||
@@ -5,7 +6,30 @@ import {
|
|||||||
encodeVarintField,
|
encodeVarintField,
|
||||||
} from "./wire.js";
|
} from "./wire.js";
|
||||||
|
|
||||||
const DEFAULT_VERSION = "3000.4.25";
|
/**
|
||||||
|
* Cognition version-gates GetChatMessage against a known Windsurf/Devin Desktop
|
||||||
|
* release. The Devin CLI build id (`3000.4.25`) is not that string and the
|
||||||
|
* server answers: "Your Windsurf version is out of date."
|
||||||
|
* Prefer the installed Devin.app product.json, then a current desktop release.
|
||||||
|
*/
|
||||||
|
const FALLBACK_WINDSURF_VERSION = "3.6.27";
|
||||||
|
const PRODUCT_JSON =
|
||||||
|
"/Applications/Devin.app/Contents/Resources/app/product.json";
|
||||||
|
|
||||||
|
function desktopWindsurfVersion(): string {
|
||||||
|
try {
|
||||||
|
if (!existsSync(PRODUCT_JSON)) return FALLBACK_WINDSURF_VERSION;
|
||||||
|
const product = JSON.parse(readFileSync(PRODUCT_JSON, "utf8")) as {
|
||||||
|
windsurfVersion?: string;
|
||||||
|
};
|
||||||
|
return product.windsurfVersion || FALLBACK_WINDSURF_VERSION;
|
||||||
|
} catch {
|
||||||
|
return FALLBACK_WINDSURF_VERSION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CLIENT_VERSION = desktopWindsurfVersion();
|
||||||
|
export const CLIENT_IDE = "windsurf";
|
||||||
|
|
||||||
export interface MetadataInput {
|
export interface MetadataInput {
|
||||||
apiKey: string;
|
apiKey: string;
|
||||||
@@ -14,10 +38,12 @@ export interface MetadataInput {
|
|||||||
requestId: bigint;
|
requestId: bigint;
|
||||||
triggerId: string;
|
triggerId: string;
|
||||||
version?: string;
|
version?: string;
|
||||||
|
ide?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildMetadata(input: MetadataInput): Buffer {
|
export function buildMetadata(input: MetadataInput): Buffer {
|
||||||
const version = input.version ?? DEFAULT_VERSION;
|
const version = input.version ?? CLIENT_VERSION;
|
||||||
|
const ide = input.ide ?? CLIENT_IDE;
|
||||||
const os =
|
const os =
|
||||||
process.platform === "darwin"
|
process.platform === "darwin"
|
||||||
? "darwin"
|
? "darwin"
|
||||||
@@ -25,7 +51,7 @@ export function buildMetadata(input: MetadataInput): Buffer {
|
|||||||
? "windows"
|
? "windows"
|
||||||
: "linux";
|
: "linux";
|
||||||
const parts: Buffer[] = [
|
const parts: Buffer[] = [
|
||||||
encodeString(1, "devin"),
|
encodeString(1, ide),
|
||||||
encodeString(2, version),
|
encodeString(2, version),
|
||||||
encodeString(3, input.apiKey),
|
encodeString(3, input.apiKey),
|
||||||
encodeString(4, "en"),
|
encodeString(4, "en"),
|
||||||
@@ -33,11 +59,11 @@ export function buildMetadata(input: MetadataInput): Buffer {
|
|||||||
encodeString(7, version),
|
encodeString(7, version),
|
||||||
encodeVarintField(9, input.requestId),
|
encodeVarintField(9, input.requestId),
|
||||||
encodeString(10, input.sessionId),
|
encodeString(10, input.sessionId),
|
||||||
encodeString(12, "devin"),
|
encodeString(12, ide),
|
||||||
encodeMessage(16, encodeTimestampBody()),
|
encodeMessage(16, encodeTimestampBody()),
|
||||||
encodeString(25, input.triggerId),
|
encodeString(25, input.triggerId),
|
||||||
encodeString(26, "Unset"),
|
encodeString(26, "Unset"),
|
||||||
encodeString(28, "devin"),
|
encodeString(28, ide),
|
||||||
];
|
];
|
||||||
if (input.userJwt) parts.push(encodeString(21, input.userJwt));
|
if (input.userJwt) parts.push(encodeString(21, input.userJwt));
|
||||||
return Buffer.concat(parts);
|
return Buffer.concat(parts);
|
||||||
|
|||||||
Reference in New Issue
Block a user