{"slug": "devinx-claude-code-on-cognition-swe-2-via-cliproxyapi-setup-guide", "title": "devinx — Claude Code on Cognition SWE-2 via cliproxyapi (setup guide)", "summary": "A developer published a setup guide for a Python shim that exposes Cognition's SWE-2 and SWE-1.x coding models through an OpenAI-compatible API, letting tools like Claude Code call them via CLIProxyAPI. The shim translates OpenAI chat completion requests into Cognition's Connect-RPC GetChatMessage calls against server.codeium.com, authenticating with the Devin CLI's stored credential.", "body_md": "|  | #!/usr/bin/env python3 | \n|  | \"\"\"OpenAI-compatible shim in front of Cognition's Connect-RPC GetChatMessage. | \n|  |  | \n|  | Serves POST /v1/chat/completions (stream + non-stream) and GET /v1/models by | \n|  | translating to exa.api_server_pb.ApiServerService/GetChatMessage against | \n|  | server.codeium.com, authenticated with the Devin CLI's stored credential. | \n|  | Runs behind CLIProxyAPI as an openai-compatibility upstream. | \n|  | \"\"\" | \n|  | import glob | \n|  | import gzip | \n|  | import json | \n|  | import os | \n|  | import re | \n|  | import struct | \n|  | import threading | \n|  | import time | \n|  | import uuid | \n|  | from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer | \n|  |  | \n|  | import requests | \n|  | from google.protobuf import descriptor_pb2, descriptor_pool, message_factory | \n|  | from google.protobuf import timestamp_pb2, duration_pb2, any_pb2, struct_pb2 | \n|  | from google.protobuf import wrappers_pb2, empty_pb2, field_mask_pb2, type_pb2 | \n|  | from google.protobuf import source_context_pb2, api_pb2 | \n|  |  | \n|  | HERE = os.path.dirname(os.path.abspath(__file__)) | \n|  | UPSTREAM = \"https://server.codeium.com\" | \n|  | AUTH_PATH = \"/exa.auth_pb.AuthService/GetUserJwt\" | \n|  | CHAT_PATH = \"/exa.api_server_pb.ApiServerService/GetChatMessage\" | \n|  | IDE_NAME = \"windsurf\" | \n|  | IDE_VERSION = \"3.51.3\" | \n|  | EXT_VERSION = \"1.48.2\" | \n|  | SESSION_PREFIX = \"devin-session-token$\" | \n|  | STOP_PATTERNS = [\"<\\|user\\|>\", \"<\\|bot\\|>\", \"<\\|context_request\\|>\", \"<\\|endoftext\\|>\", \"<\\|end_of_turn\\|>\"] | \n|  |  | \n|  | MODELS = [ | \n|  | \"swe-2-max\", \"swe-2-high\", \"swe-2-medium\", | \n|  | \"swe-1-7\", \"swe-1-7-medium\", \"swe-1-7-lightning\", \"swe-1-7-lightning-medium\", | \n|  | \"swe-1-6\", \"swe-1-6-fast\", | \n|  | ] | \n|  |  | \n|  | SRC_USER, SRC_SYSTEM, SRC_TOOL = 1, 2, 4 | \n|  | REQ_CASCADE, PLANNER_DEFAULT = 5, 1 | \n|  | CACHE_EPHEMERAL = 1 | \n|  | STOP_MAX_TOKENS = 3 | \n|  |  | \n|  | pool = descriptor_pool.DescriptorPool() | \n|  | for _m in (timestamp_pb2, duration_pb2, any_pb2, struct_pb2, descriptor_pb2, | \n|  | wrappers_pb2, empty_pb2, field_mask_pb2, type_pb2, source_context_pb2, api_pb2): | \n|  | _fd = descriptor_pb2.FileDescriptorProto() | \n|  | _fd.ParseFromString(_m.DESCRIPTOR.serialized_pb) | \n|  | try: | \n|  | pool.Add(_fd) | \n|  | except Exception: | \n|  | pass | \n|  | _fdps = {} | \n|  | for _p in glob.glob(os.path.join(HERE, \"*.fdp\")): | \n|  | _fd = descriptor_pb2.FileDescriptorProto() | \n|  | _fd.ParseFromString(open(_p, \"rb\").read()) | \n|  | _fdps[_fd.name] = _fd | \n|  | _added = set() | \n|  | for _ in range(40): | \n|  | for _name, _fd in _fdps.items(): | \n|  | if _name in _added: | \n|  | continue | \n|  | try: | \n|  | pool.Add(_fd) | \n|  | _added.add(_name) | \n|  | except Exception: | \n|  | pass | \n|  |  | \n|  |  | \n|  | def _msg(name): | \n|  | return message_factory.GetMessageClass(pool.FindMessageTypeByName(name)) | \n|  |  | \n|  |  | \n|  | GetUserJwtRequest = _msg(\"exa.auth_pb.GetUserJwtRequest\") | \n|  | GetUserJwtResponse = _msg(\"exa.auth_pb.GetUserJwtResponse\") | \n|  | GetChatMessageRequest = _msg(\"exa.api_server_pb.GetChatMessageRequest\") | \n|  | GetChatMessageResponse = _msg(\"exa.api_server_pb.GetChatMessageResponse\") | \n|  |  | \n|  |  | \n|  | def _load_key(): | \n|  | if os.environ.get(\"DEVIN_SHIM_API_KEY\"): | \n|  | return os.environ[\"DEVIN_SHIM_API_KEY\"] | \n|  | # Prefer the shim's own login (created via `XDG_DATA_HOME=~/devin-shim/data | \n|  | # devin auth login`); fall back to the Devin CLI's credential. | \n|  | for cred in (os.path.expanduser(\"~/devin-shim/data/devin/credentials.toml\"), | \n|  | os.path.expanduser(\"~/.local/share/devin/credentials.toml\")): | \n|  | if not os.path.exists(cred): | \n|  | continue | \n|  | for line in open(cred): | \n|  | if line.startswith(\"windsurf_api_key\"): | \n|  | return line.split('\"')[1] | \n|  | raise RuntimeError(\"no devin credential found\") | \n|  |  | \n|  |  | \n|  | API_KEY = _load_key() | \n|  | if not API_KEY.startswith(SESSION_PREFIX): | \n|  | API_KEY = SESSION_PREFIX + API_KEY | \n|  |  | \n|  | _jwt_lock = threading.Lock() | \n|  | _jwt = {\"token\": None, \"exp\": 0.0, \"base\": None} | \n|  |  | \n|  |  | \n|  | def _metadata(jwt=\"\"): | \n|  | return { | \n|  | \"api_key\": API_KEY, | \n|  | \"user_jwt\": jwt, | \n|  | \"ide_name\": IDE_NAME, | \n|  | \"ide_version\": IDE_VERSION, | \n|  | \"extension_name\": \"windsurf\", | \n|  | \"extension_version\": EXT_VERSION, | \n|  | \"locale\": \"en\", | \n|  | \"session_id\": str(uuid.uuid4()), | \n|  | \"request_id\": uuid.uuid4().int & (2**63 - 1), | \n|  | } | \n|  |  | \n|  |  | \n|  | def _jwt_expiry(token): | \n|  | try: | \n|  | import base64 | \n|  | payload = token.split(\".\")[1] | \n|  | payload += \"=\" * (-len(payload) % 4) | \n|  | return json.loads(base64.urlsafe_b64decode(payload)).get(\"exp\", 0) | \n|  | except Exception: | \n|  | return 0.0 | \n|  |  | \n|  |  | \n|  | def get_jwt(force=False): | \n|  | with _jwt_lock: | \n|  | now = time.time() | \n|  | if not force and _jwt[\"token\"] and _jwt[\"exp\"] - 60 > now: | \n|  | return _jwt[\"token\"], _jwt[\"base\"] | \n|  | req = GetUserJwtRequest(metadata=_metadata()) | \n|  | r = requests.post(UPSTREAM + AUTH_PATH, data=req.SerializeToString(), | \n|  | headers={\"content-type\": \"application/proto\", | \n|  | \"connect-protocol-version\": \"1\"}, timeout=30) | \n|  | r.raise_for_status() | \n|  | resp = GetUserJwtResponse() | \n|  | try: | \n|  | resp.ParseFromString(r.content) | \n|  | except Exception: | \n|  | resp.ParseFromString(gzip.decompress(r.content)) | \n|  | if not resp.user_jwt: | \n|  | raise RuntimeError(\"GetUserJwt returned empty jwt\") | \n|  | _jwt[\"token\"] = resp.user_jwt | \n|  | _jwt[\"exp\"] = _jwt_expiry(resp.user_jwt) or now + 3300 | \n|  | _jwt[\"base\"] = resp.custom_api_server_url.strip() or None | \n|  | return _jwt[\"token\"], _jwt[\"base\"] | \n|  |  | \n|  |  | \n|  | def _text_of(content): | \n|  | if isinstance(content, str): | \n|  | return content | \n|  | out = [] | \n|  | for part in content or []: | \n|  | if part.get(\"type\") == \"text\": | \n|  | out.append(part.get(\"text\", \"\")) | \n|  | return \"\".join(out) | \n|  |  | \n|  |  | \n|  | # Cognition's input classifier rejects these Claude Code system-prompt blocks | \n|  | # (competitor identity, security-policy vocabulary, product marketing + URLs). | \n|  | # Rewrite them to neutral equivalents; behavior instructions are unchanged. | \n|  | _SYS_REWRITES = [ | \n|  | (re.compile(r\"You are (?:a )?Claude[^.]*\\.\"), \"You are a coding agent.\"), | \n|  | (re.compile(r\"IMPORTANT: Assist with authorized security testing.*?(?=\\n\\s*\\n\\|\\Z)\", re.S), | \n|  | \"Assist with authorized security testing and defensive security work; refuse harmful or destructive requests.\"), | \n|  | (re.compile(r\"\\n?\\s*-?\\s*Claude Code is available[^\\n]*\"), \"\"), | \n|  | (re.compile(r\"- For clear communication with the user the assistant MUST avoid using emojis\\.\"), | \n|  | \"- For clear communication with the user, avoid emojis.\"), | \n|  | ] | \n|  |  | \n|  |  | \n|  | def _scrub_system(text): | \n|  | for rx, rep in _SYS_REWRITES: | \n|  | text = rx.sub(rep, text) | \n|  | return text | \n|  |  | \n|  |  | \n|  | # TaskOutput's shipped description trips the same classifier in combination | \n|  | # (per-line fragments pass). It is deprecated upstream; send a short equivalent. | \n|  | _TOOL_DESC_REWRITES = { | \n|  | \"TaskOutput\": \"Get the output of a running or completed background task (shell, agent, or remote session) by task_id.\", | \n|  | } | \n|  |  | \n|  |  | \n|  | def _images_of(content): | \n|  | if isinstance(content, str) or not content: | \n|  | return [] | \n|  | out = [] | \n|  | for part in content or []: | \n|  | if part.get(\"type\") == \"image_url\": | \n|  | url = part.get(\"image_url\", {}).get(\"url\", \"\") | \n|  | if url.startswith(\"data:\"): | \n|  | mime, _, b64 = url[5:].partition(\";base64,\") | \n|  | out.append({\"base64_data\": b64, \"mime_type\": mime or \"image/png\"}) | \n|  | return out | \n|  |  | \n|  |  | \n|  | def build_request(body): | \n|  | system_parts, prompts = [], [] | \n|  | cascade_id = str(uuid.uuid4()) | \n|  | for i, m in enumerate(body.get(\"messages\", [])): | \n|  | role = m.get(\"role\") | \n|  | mid = str(uuid.uuid5(uuid.NAMESPACE_URL, f\"{cascade_id}\\0{i}\\0{role}\")) | \n|  | if role in (\"system\", \"developer\"): | \n|  | system_parts.append(_scrub_system(_text_of(m.get(\"content\")))) | \n|  | elif role == \"user\": | \n|  | prompts.append({\"message_id\": mid, \"source\": SRC_USER, | \n|  | \"prompt\": _text_of(m.get(\"content\")), | \n|  | \"images\": _images_of(m.get(\"content\"))}) | \n|  | elif role == \"assistant\": | \n|  | tcs = [{\"id\": tc.get(\"id\", \"\"), \"name\": tc.get(\"function\", {}).get(\"name\", \"\"), | \n|  | \"arguments_json\": tc.get(\"function\", {}).get(\"arguments\", \"\")} | \n|  | for tc in m.get(\"tool_calls\") or []] | \n|  | text = _text_of(m.get(\"content\")) | \n|  | thinking = m.get(\"reasoning_content\") or \"\" | \n|  | prompts.append({\"message_id\": mid, \"source\": SRC_SYSTEM, \"prompt\": text, | \n|  | \"thinking\": thinking, \"tool_calls\": tcs}) | \n|  | elif role == \"tool\": | \n|  | prompts.append({\"message_id\": mid, \"source\": SRC_TOOL, | \n|  | \"tool_call_id\": m.get(\"tool_call_id\", \"\"), | \n|  | \"prompt\": _text_of(m.get(\"content\")), | \n|  | \"images\": _images_of(m.get(\"content\"))}) | \n|  | tools = [{\"name\": t[\"function\"][\"name\"], | \n|  | \"description\": _TOOL_DESC_REWRITES.get(t[\"function\"][\"name\"], | \n|  | t[\"function\"].get(\"description\", \"\")), | \n|  | \"json_schema_string\": json.dumps(t[\"function\"].get(\"parameters\") or {}), | \n|  | \"strict\": bool(t[\"function\"].get(\"strict\"))} | \n|  | for t in body.get(\"tools\") or [] if t.get(\"type\") == \"function\"] | \n|  | tc = body.get(\"tool_choice\") | \n|  | tool_choice = {\"option_name\": \"auto\"} | \n|  | if isinstance(tc, str) and tc in (\"auto\", \"required\", \"none\"): | \n|  | tool_choice = {\"option_name\": tc} | \n|  | elif isinstance(tc, dict): | \n|  | fn = (tc.get(\"function\") or {}).get(\"name\") | \n|  | if fn: | \n|  | tool_choice = {\"tool_name\": fn} | \n|  | stops = list(STOP_PATTERNS) | \n|  | stop = body.get(\"stop\") | \n|  | stops += [stop] if isinstance(stop, str) else list(stop or []) | \n|  | conf = {\"num_completions\": 1, \"max_newlines\": 200, \"top_k\": 50, | \n|  | \"stop_patterns\": stops, \"fim_eot_prob_threshold\": 1} | \n|  | conf[\"max_tokens\"] = int(body.get(\"max_completion_tokens\") or body.get(\"max_tokens\") or 64000) | \n|  | if body.get(\"temperature\") is not None: | \n|  | conf[\"temperature\"] = conf[\"first_temperature\"] = float(body[\"temperature\"]) | \n|  | else: | \n|  | conf[\"temperature\"] = conf[\"first_temperature\"] = 0.4 | \n|  | if body.get(\"top_p\") is not None: | \n|  | conf[\"top_p\"] = float(body[\"top_p\"]) | \n|  | else: | \n|  | conf[\"top_p\"] = 1 | \n|  | model = body.get(\"model\", \"swe-2-max\") | \n|  | if \"/\" in model: | \n|  | model = model.rsplit(\"/\", 1)[-1] | \n|  | return GetChatMessageRequest( | \n|  | metadata=_metadata(get_jwt()[0]), | \n|  | prompt=\"\\n\\n\".join(p for p in system_parts if p), | \n|  | chat_message_prompts=prompts, | \n|  | chat_model_uid=model, | \n|  | request_type=REQ_CASCADE, | \n|  | planner_mode=PLANNER_DEFAULT, | \n|  | tool_choice=tool_choice, | \n|  | system_prompt_cache_options={\"type\": CACHE_EPHEMERAL}, | \n|  | disable_parallel_tool_calls=False, | \n|  | cascade_id=cascade_id, | \n|  | execution_id=str(uuid.uuid4()), | \n|  | configuration=conf, | \n|  | tools=tools, | \n|  | ), model | \n|  |  | \n|  |  | \n|  | def chat_stream(req): | \n|  | \"\"\"Yield (GetChatMessageResponse, None) per frame or (None, error_str) on trailer error.\"\"\" | \n|  | jwt, base = get_jwt() | \n|  | req.metadata.user_jwt = jwt | \n|  | body = req.SerializeToString() | \n|  | for attempt in range(2): | \n|  | gz = gzip.compress(body) | \n|  | frame = bytes([1]) + struct.pack(\">I\", len(gz)) + gz | \n|  | r = requests.post((base or UPSTREAM) + CHAT_PATH, data=frame, | \n|  | headers={\"content-type\": \"application/connect+proto\", | \n|  | \"connect-protocol-version\": \"1\", | \n|  | \"connect-content-encoding\": \"gzip\", | \n|  | \"connect-accept-encoding\": \"gzip\", | \n|  | \"user-agent\": \"connect-go/1.18.1 (go1.26.3)\"}, | \n|  | timeout=600, stream=True) | \n|  | if r.status_code == 200: | \n|  | break | \n|  | if r.status_code in (401, 403) and attempt == 0: | \n|  | jwt, base = get_jwt(force=True) | \n|  | req.metadata.user_jwt = jwt | \n|  | body = req.SerializeToString() | \n|  | continue | \n|  | yield None, f\"upstream {r.status_code}: {r.text[:400]}\" | \n|  | return | \n|  | buf = b\"\" | \n|  | for chunk in r.iter_content(65536): | \n|  | buf += chunk | \n|  | while len(buf) >= 5: | \n|  | flag = buf[0] | \n|  | ln = struct.unpack(\">I\", buf[1:5])[0] | \n|  | if len(buf) < 5 + ln: | \n|  | break | \n|  | payload = buf[5:5 + ln] | \n|  | buf = buf[5 + ln:] | \n|  | if flag & 2: | \n|  | trailer = gzip.decompress(payload) if flag & 1 else payload | \n|  | try: | \n|  | err = json.loads(trailer).get(\"error\") or {} | \n|  | except Exception: | \n|  | err = {} | \n|  | if err.get(\"message\"): | \n|  | yield None, f\"{err.get('code', 'error')}: {err['message']}\" | \n|  | continue | \n|  | raw = gzip.decompress(payload) if flag & 1 else payload | \n|  | msg = GetChatMessageResponse() | \n|  | msg.ParseFromString(raw) | \n|  | yield msg, None | \n|  |  | \n|  |  | \n|  | def openai_chunk(model, delta=None, finish=None, usage=None): | \n|  | ch = {\"index\": 0} | \n|  | if delta is not None: | \n|  | ch[\"delta\"] = delta | \n|  | if finish: | \n|  | ch[\"finish_reason\"] = finish | \n|  | out = {\"id\": \"chatcmpl-devin\", \"object\": \"chat.completion.chunk\", | \n|  | \"created\": int(time.time()), \"model\": model, \"choices\": [ch]} | \n|  | if usage: | \n|  | out[\"usage\"] = usage | \n|  | return out | \n|  |  | \n|  |  | \n|  | def sse(obj): | \n|  | return f\"data: {json.dumps(obj)}\\n\\n\".encode() | \n|  |  | \n|  |  | \n|  | def run_chat(body, wfile): | \n|  | \"\"\"Translate one OpenAI chat.completions call; returns (final_msg_dict, usage, error).\"\"\" | \n|  | try: | \n|  | req, model = build_request(body) | \n|  | except Exception as e: | \n|  | return None, None, f\"request build: {e}\" | \n|  | stream = bool(body.get(\"stream\")) | \n|  | w = wfile if stream else None | \n|  | headers_sent = False | \n|  | # Cognition's input classifier denies borderline payloads nondeterministically | \n|  | # (same body observed pass/fail). Retry while nothing reached the client. | \n|  | for attempt in range(3): | \n|  | if attempt: | \n|  | req, model = build_request(body) | \n|  | if w and not headers_sent: | \n|  | w.write(b\"HTTP/1.1 200 OK\\r\\ncontent-type: text/event-stream\\r\\n\" | \n|  | b\"cache-control: no-cache\\r\\nconnection: close\\r\\n\\r\\n\") | \n|  | w.flush() | \n|  | w.write(sse(openai_chunk(model, delta={\"role\": \"assistant\"}))) | \n|  | w.flush() | \n|  | headers_sent = True | \n|  | text, thinking = [], [] | \n|  | tool_blocks = {}   # id -> {\"name\":..., \"json\":...} | \n|  | tool_order = [] | \n|  | usage = {} | \n|  | stop = 0 | \n|  | err = None | \n|  | emitted = False | \n|  | for msg, e in chat_stream(req): | \n|  | if e: | \n|  | err = e | \n|  | break | \n|  | if msg.delta_text: | \n|  | text.append(msg.delta_text) | \n|  | if w: | \n|  | emitted = True | \n|  | w.write(sse(openai_chunk(model, delta={\"content\": msg.delta_text}))) | \n|  | w.flush() | \n|  | if msg.delta_thinking: | \n|  | thinking.append(msg.delta_thinking) | \n|  | if w: | \n|  | emitted = True | \n|  | w.write(sse(openai_chunk(model, delta={\"reasoning_content\": msg.delta_thinking}))) | \n|  | w.flush() | \n|  | for tc in msg.delta_tool_calls: | \n|  | tid = tc.id or (tool_order[-1] if tool_order else \"\") | \n|  | if not tid: | \n|  | continue | \n|  | if tid not in tool_blocks: | \n|  | tool_blocks[tid] = {\"name\": tc.name, \"json\": \"\"} | \n|  | tool_order.append(tid) | \n|  | if w: | \n|  | emitted = True | \n|  | idx = tool_order.index(tid) | \n|  | w.write(sse(openai_chunk(model, delta={\"tool_calls\": [ | \n|  | {\"index\": idx, \"id\": tid, \"type\": \"function\", | \n|  | \"function\": {\"name\": tc.name, \"arguments\": \"\"}}]}))) | \n|  | w.flush() | \n|  | if tc.name: | \n|  | tool_blocks[tid][\"name\"] = tc.name | \n|  | if tc.arguments_json: | \n|  | prev = tool_blocks[tid][\"json\"] | \n|  | acc = tc.arguments_json if tc.arguments_json.startswith(prev) else prev + tc.arguments_json | \n|  | delta = acc[len(prev):] | \n|  | tool_blocks[tid][\"json\"] = acc | \n|  | if w and delta: | \n|  | emitted = True | \n|  | idx = tool_order.index(tid) | \n|  | w.write(sse(openai_chunk(model, delta={\"tool_calls\": [ | \n|  | {\"index\": idx, \"function\": {\"arguments\": delta}}]}))) | \n|  | w.flush() | \n|  | if msg.usage.input_tokens: | \n|  | usage = {\"prompt_tokens\": int(msg.usage.input_tokens), | \n|  | \"completion_tokens\": int(msg.usage.output_tokens), | \n|  | \"total_tokens\": int(msg.usage.input_tokens + msg.usage.output_tokens)} | \n|  | stop = msg.stop_reason | \n|  | if err and not emitted and attempt < 2 and \"permission_denied\" in err: | \n|  | print(f\"upstream permission_denied, retrying (attempt {attempt + 2}/3)\", flush=True) | \n|  | continue | \n|  | break | \n|  | if err: | \n|  | if w: | \n|  | w.write(sse({\"error\": {\"message\": err, \"type\": \"upstream_error\"}})) | \n|  | w.write(b\"data: [DONE]\\n\\n\") | \n|  | w.flush() | \n|  | return None, None, err | \n|  | finish = \"tool_calls\" if tool_blocks else \"stop\" | \n|  | if not tool_blocks and stop == STOP_MAX_TOKENS: | \n|  | finish = \"length\" | \n|  | if w: | \n|  | final = openai_chunk(model, delta={}, finish=finish, | \n|  | usage=usage if (body.get(\"stream_options\") or {}).get(\"include_usage\") else None) | \n|  | w.write(sse(final)) | \n|  | w.write(b\"data: [DONE]\\n\\n\") | \n|  | w.flush() | \n|  | return None, None, None | \n|  | msg_out = {\"role\": \"assistant\", \"content\": \"\".join(text)} | \n|  | if thinking: | \n|  | msg_out[\"reasoning_content\"] = \"\".join(thinking) | \n|  | if tool_blocks: | \n|  | msg_out[\"tool_calls\"] = [ | \n|  | {\"id\": tid, \"type\": \"function\", | \n|  | \"function\": {\"name\": b[\"name\"], \"arguments\": b[\"json\"]}} | \n|  | for tid, b in ((tid, tool_blocks[tid]) for tid in tool_order)] | \n|  | msg_out[\"content\"] = msg_out[\"content\"] or None | \n|  | resp = {\"id\": \"chatcmpl-devin\", \"object\": \"chat.completion\", | \n|  | \"created\": int(time.time()), \"model\": model, | \n|  | \"choices\": [{\"index\": 0, \"message\": msg_out, \"finish_reason\": finish}]} | \n|  | if usage: | \n|  | resp[\"usage\"] = usage | \n|  | return resp, usage, None | \n|  |  | \n|  |  | \n|  | class Handler(BaseHTTPRequestHandler): | \n|  | protocol_version = \"HTTP/1.1\" | \n|  |  | \n|  | def log_message(self, fmt, *args): | \n|  | print(f\"{self.address_string()} {fmt % args}\", flush=True) | \n|  |  | \n|  | def _json(self, code, obj): | \n|  | data = json.dumps(obj).encode() | \n|  | self.send_response(code) | \n|  | self.send_header(\"content-type\", \"application/json\") | \n|  | self.send_header(\"content-length\", str(len(data))) | \n|  | self.end_headers() | \n|  | self.wfile.write(data) | \n|  |  | \n|  | def do_GET(self): | \n|  | if self.path.split(\"?\")[0] in (\"/v1/models\", \"/models\"): | \n|  | self._json(200, {\"object\": \"list\", \"data\": [ | \n|  | {\"id\": m, \"object\": \"model\", \"created\": 0, \"owned_by\": \"devin\"} for m in MODELS]}) | \n|  | else: | \n|  | self._json(404, {\"error\": {\"message\": \"not found\", \"type\": \"invalid_request_error\"}}) | \n|  |  | \n|  | def do_POST(self): | \n|  | path = self.path.split(\"?\")[0] | \n|  | if path not in (\"/v1/chat/completions\", \"/chat/completions\"): | \n|  | self._json(404, {\"error\": {\"message\": \"not found\", \"type\": \"invalid_request_error\"}}) | \n|  | return | \n|  | try: | \n|  | raw = self.rfile.read(int(self.headers.get(\"content-length\", 0))) | \n|  | if os.environ.get(\"DEVIN_SHIM_DUMP\"): | \n|  | with open(os.environ[\"DEVIN_SHIM_DUMP\"] + f\".{time.time_ns()}.json\", \"wb\") as fh: | \n|  | fh.write(raw) | \n|  | body = json.loads(raw) | \n|  | except Exception as e: | \n|  | self._json(400, {\"error\": {\"message\": f\"bad json: {e}\", \"type\": \"invalid_request_error\"}}) | \n|  | return | \n|  | if body.get(\"stream\"): | \n|  | # run_chat owns the raw socket from here | \n|  | resp, _, err = run_chat(body, self.wfile) | \n|  | if err: | \n|  | return | \n|  | return | \n|  | resp, _, err = run_chat(body, None) | \n|  | if err: | \n|  | self._json(502, {\"error\": {\"message\": err, \"type\": \"upstream_error\"}}) | \n|  | else: | \n|  | self._json(200, resp) | \n|  |  | \n|  |  | \n|  | if __name__ == \"__main__\": | \n|  | port = int(os.environ.get(\"DEVIN_SHIM_PORT\", \"8321\")) | \n|  | print(f\"devin-shim listening on 127.0.0.1:{port}\", flush=True) | \n|  | ThreadingHTTPServer((\"127.0.0.1\", port), Handler).serve_forever() |", "url": "https://wpnews.pro/news/devinx-claude-code-on-cognition-swe-2-via-cliproxyapi-setup-guide", "canonical_source": "https://gist.github.com/future3OOO/9d829db4dda0a5f539028236c7091767", "published_at": "2026-09-11 05:36:01+00:00", "updated_at": "2026-09-11 05:55:55.691462+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "ai-agents", "large-language-models"], "entities": ["Cognition", "Claude Code", "CLIProxyAPI", "Devin", "SWE-2", "server.codeium.com", "Windsurf"], "alternates": {"html": "https://wpnews.pro/news/devinx-claude-code-on-cognition-swe-2-via-cliproxyapi-setup-guide", "markdown": "https://wpnews.pro/news/devinx-claude-code-on-cognition-swe-2-via-cliproxyapi-setup-guide.md", "text": "https://wpnews.pro/news/devinx-claude-code-on-cognition-swe-2-via-cliproxyapi-setup-guide.txt", "jsonld": "https://wpnews.pro/news/devinx-claude-code-on-cognition-swe-2-via-cliproxyapi-setup-guide.jsonld"}}