workbuddy2api 2.0.2__tar.gz → 2.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (19) hide show
  1. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/PKG-INFO +5 -3
  2. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/README.md +4 -2
  3. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/pyproject.toml +1 -1
  4. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/src/codebuddy_proxy/__main__.py +8 -1
  5. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/src/codebuddy_proxy/codebuddy_client_demo.py +48 -3
  6. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/src/workbuddy2api.egg-info/PKG-INFO +5 -3
  7. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/LICENSE +0 -0
  8. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/setup.cfg +0 -0
  9. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/src/codebuddy_proxy/anthropic_adapter.py +0 -0
  10. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/src/codebuddy_proxy/desensitize.py +0 -0
  11. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/src/codebuddy_proxy/dsml_parser.py +0 -0
  12. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/src/codebuddy_proxy/projection_metadata.py +0 -0
  13. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/src/codebuddy_proxy/responses_adapter.py +0 -0
  14. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/src/codebuddy_proxy/responses_projection.py +0 -0
  15. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/src/workbuddy2api.egg-info/SOURCES.txt +0 -0
  16. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/src/workbuddy2api.egg-info/dependency_links.txt +0 -0
  17. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/src/workbuddy2api.egg-info/entry_points.txt +0 -0
  18. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/src/workbuddy2api.egg-info/requires.txt +0 -0
  19. {workbuddy2api-2.0.2 → workbuddy2api-2.0.3}/src/workbuddy2api.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: workbuddy2api
3
- Version: 2.0.2
3
+ Version: 2.0.3
4
4
  Summary: Local OpenAI/Responses/Anthropic compatible proxy for CodeBuddy
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -72,8 +72,10 @@ uv run python -m codebuddy_proxy --login --desensitize
72
72
 
73
73
  ```bash
74
74
  # 使用最新版本(推荐)
75
- uv run --with workbuddy2api python -m codebuddy_proxy --desensitize \
76
- --log-file "$HOME/.workbuddy2api/codebuddy-proxy.jsonl"
75
+ uv run --with workbuddy2api python -m codebuddy_proxy --desensitize
76
+
77
+ # 首次使用:登录并启动
78
+ uv run --with workbuddy2api python -m codebuddy_proxy --login --desensitize
77
79
  ```
78
80
 
79
81
  默认监听 `http://127.0.0.1:8787`
@@ -57,8 +57,10 @@ uv run python -m codebuddy_proxy --login --desensitize
57
57
 
58
58
  ```bash
59
59
  # 使用最新版本(推荐)
60
- uv run --with workbuddy2api python -m codebuddy_proxy --desensitize \
61
- --log-file "$HOME/.workbuddy2api/codebuddy-proxy.jsonl"
60
+ uv run --with workbuddy2api python -m codebuddy_proxy --desensitize
61
+
62
+ # 首次使用:登录并启动
63
+ uv run --with workbuddy2api python -m codebuddy_proxy --login --desensitize
62
64
  ```
63
65
 
64
66
  默认监听 `http://127.0.0.1:8787`
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "workbuddy2api"
3
- version = "2.0.2"
3
+ version = "2.0.3"
4
4
  description = "Local OpenAI/Responses/Anthropic compatible proxy for CodeBuddy"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -332,7 +332,7 @@ class RemoteConfigCache:
332
332
 
333
333
  # 构造请求头(包含认证信息)
334
334
  headers = state.client.auth_headers()
335
- headers["User-Agent"] = "CodeBuddy-Proxy/2.0"
335
+ headers["User-Agent"] = "Mozilla/5.0 (compatible; Genie-IDE/1.0)"
336
336
  headers["Accept"] = "application/json"
337
337
 
338
338
  # 发起请求(超时 5 秒,匹配插件)
@@ -897,11 +897,18 @@ async def forward_chat(
897
897
 
898
898
  url = state.client.endpoint + "/v2/chat/completions"
899
899
  headers = {
900
+ "User-Agent": "Mozilla/5.0 (compatible; Genie-IDE/1.0)",
900
901
  **state.client.auth_headers(),
901
902
  "Content-Type": "application/json",
902
903
  "Accept": "text/event-stream",
903
904
  }
904
905
 
906
+ # 🔍 调试:输出实际发送的IDE识别headers
907
+ if state.logger:
908
+ ide_headers = {k: v for k, v in headers.items()
909
+ if k.startswith("X-IDE-") or k == "X-Product-Version" or k == "X-Machine-Id"}
910
+ diagnostic("upstream_ide_headers", **ide_headers)
911
+
905
912
  if stream:
906
913
  # 流式:直接转发
907
914
  return StreamingResponse(
@@ -81,8 +81,11 @@ class CodeBuddyClient:
81
81
  body: Any = None,
82
82
  timeout: float = 30,
83
83
  ) -> Any:
84
- request_headers = {"User-Agent": "CodeBuddyClientDemo/1.0"}
85
- request_headers.update(headers or {})
84
+ # 🔥 所有请求都必须包含这两个基础标识(匹配插件行为)
85
+ request_headers = {
86
+ "User-Agent": "Mozilla/5.0 (compatible; Genie-IDE/1.0)",
87
+ "X-Product-Code": "codebuddy",
88
+ }
86
89
  data = None
87
90
  if body is not None:
88
91
  data = json.dumps(body).encode("utf-8")
@@ -110,9 +113,20 @@ class CodeBuddyClient:
110
113
  raise CodeBuddyError(f"{path} 返回的不是 JSON: {raw[:300]!r}") from exc
111
114
 
112
115
  def auth_headers(self, *, access: bool = True, refresh: bool = False) -> dict[str, str]:
116
+ """构造认证 headers,模拟插件行为"""
113
117
  account = self.session.get("account") or {}
114
118
  auth = self.session.get("auth") or {}
115
- headers: dict[str, str] = {}
119
+ headers: dict[str, str] = {
120
+ # 🔥 关键标识:所有请求都需要这个 header
121
+ "X-Product-Code": "codebuddy",
122
+ # 🔥 IDE 识别信息(服务端用于识别客户端类型)
123
+ "X-IDE-Type": "vscode",
124
+ "X-IDE-Name": "Visual Studio Code",
125
+ "X-IDE-Version": "1.70.2", # VSCode 最低版本要求
126
+ "X-Product-Version": "4.10.33259736", # 插件版本
127
+ "X-Machine-Id": self._get_machine_id(),
128
+ }
129
+
116
130
  if account.get("uid"):
117
131
  headers["X-User-Id"] = str(account["uid"])
118
132
  if access and auth.get("accessToken"):
@@ -122,12 +136,41 @@ class CodeBuddyClient:
122
136
  if account.get("enterpriseId"):
123
137
  headers["X-Enterprise-Id"] = str(account["enterpriseId"])
124
138
  headers["X-Tenant-Id"] = str(account["enterpriseId"])
139
+ if account.get("departmentInfo"):
140
+ # 🔥 新增:部门信息(如果有)
141
+ headers["X-Department-Info"] = str(account["departmentInfo"])
125
142
  if auth.get("domain"):
126
143
  # The extension calls this the domain header. The server accepts
127
144
  # X-Domain for the plugin protocol.
128
145
  headers["X-Domain"] = str(auth["domain"])
129
146
  return headers
130
147
 
148
+ def _get_machine_id(self) -> str:
149
+ """获取或生成机器ID(模拟VSCode的machineId)"""
150
+ import hashlib
151
+ import platform
152
+ import uuid
153
+
154
+ # 尝试从session读取已保存的machineId
155
+ saved_machine_id = self.session.get("machineId")
156
+ if saved_machine_id:
157
+ return str(saved_machine_id)
158
+
159
+ # 生成一个稳定的machineId(基于主机名和用户)
160
+ try:
161
+ hostname = platform.node()
162
+ username = os.environ.get("USER") or os.environ.get("USERNAME") or "unknown"
163
+ seed = f"{hostname}-{username}"
164
+ machine_id = str(uuid.uuid5(uuid.NAMESPACE_DNS, seed))
165
+ except Exception:
166
+ # 如果失败,生成随机ID
167
+ machine_id = str(uuid.uuid4())
168
+
169
+ # 保存到session
170
+ self.session["machineId"] = machine_id
171
+ self._save_session(self.session)
172
+ return machine_id
173
+
131
174
  def login(self, *, open_browser: bool = True, timeout: int = 300) -> None:
132
175
  no_auth = {
133
176
  "X-No-Authorization": "true",
@@ -250,6 +293,8 @@ class CodeBuddyClient:
250
293
  f"{self.endpoint}/v2/chat/completions",
251
294
  data=json.dumps(payload).encode("utf-8"),
252
295
  headers={
296
+ "User-Agent": "Mozilla/5.0 (compatible; Genie-IDE/1.0)",
297
+ "X-Product-Code": "codebuddy",
253
298
  **self.auth_headers(),
254
299
  "Content-Type": "application/json",
255
300
  "Accept": "text/event-stream",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: workbuddy2api
3
- Version: 2.0.2
3
+ Version: 2.0.3
4
4
  Summary: Local OpenAI/Responses/Anthropic compatible proxy for CodeBuddy
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -72,8 +72,10 @@ uv run python -m codebuddy_proxy --login --desensitize
72
72
 
73
73
  ```bash
74
74
  # 使用最新版本(推荐)
75
- uv run --with workbuddy2api python -m codebuddy_proxy --desensitize \
76
- --log-file "$HOME/.workbuddy2api/codebuddy-proxy.jsonl"
75
+ uv run --with workbuddy2api python -m codebuddy_proxy --desensitize
76
+
77
+ # 首次使用:登录并启动
78
+ uv run --with workbuddy2api python -m codebuddy_proxy --login --desensitize
77
79
  ```
78
80
 
79
81
  默认监听 `http://127.0.0.1:8787`
File without changes
File without changes