-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathupstream_taxonomy.py
More file actions
95 lines (80 loc) · 2.65 KB
/
upstream_taxonomy.py
File metadata and controls
95 lines (80 loc) · 2.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
from __future__ import annotations
from dataclasses import dataclass
import httpx
from a2a.types import TaskState
@dataclass(frozen=True)
class UpstreamHTTPErrorProfile:
error_type: str
state: TaskState
default_message: str
_UPSTREAM_HTTP_ERROR_PROFILE_BY_STATUS: dict[int, UpstreamHTTPErrorProfile] = {
400: UpstreamHTTPErrorProfile(
"UPSTREAM_BAD_REQUEST",
TaskState.failed,
"OpenCode rejected the request due to invalid input",
),
401: UpstreamHTTPErrorProfile(
"UPSTREAM_UNAUTHORIZED",
TaskState.auth_required,
"OpenCode rejected the request due to authentication failure",
),
403: UpstreamHTTPErrorProfile(
"UPSTREAM_PERMISSION_DENIED",
TaskState.failed,
"OpenCode rejected the request due to insufficient permissions",
),
404: UpstreamHTTPErrorProfile(
"UPSTREAM_RESOURCE_NOT_FOUND",
TaskState.failed,
"OpenCode rejected the request because the target resource was not found",
),
429: UpstreamHTTPErrorProfile(
"UPSTREAM_QUOTA_EXCEEDED",
TaskState.failed,
"OpenCode rejected the request due to quota limits",
),
}
def resolve_upstream_http_error_profile(status: int) -> UpstreamHTTPErrorProfile:
if status in _UPSTREAM_HTTP_ERROR_PROFILE_BY_STATUS:
return _UPSTREAM_HTTP_ERROR_PROFILE_BY_STATUS[status]
if 400 <= status < 500:
return UpstreamHTTPErrorProfile(
"UPSTREAM_CLIENT_ERROR",
TaskState.failed,
f"OpenCode rejected the request with client error {status}",
)
if status >= 500:
return UpstreamHTTPErrorProfile(
"UPSTREAM_SERVER_ERROR",
TaskState.failed,
f"OpenCode rejected the request with server error {status}",
)
return UpstreamHTTPErrorProfile(
"UPSTREAM_HTTP_ERROR",
TaskState.failed,
f"OpenCode rejected the request with HTTP status {status}",
)
def extract_upstream_error_detail(response: httpx.Response | None) -> str | None:
if response is None:
return None
payload = None
try:
payload = response.json()
except Exception:
payload = None
if isinstance(payload, dict):
for key in ("detail", "error", "message"):
value = payload.get(key)
if isinstance(value, str):
value = value.strip()
if value:
return value
text = response.text.strip()
if text:
return text[:512]
return None
__all__ = [
"UpstreamHTTPErrorProfile",
"extract_upstream_error_detail",
"resolve_upstream_http_error_profile",
]