fix fresh-host acceptance and document real-host debugging learnings
This commit is contained in:
@@ -41,6 +41,20 @@ if [[ -z "$upstream_key" ]]; then
|
||||
exit 2
|
||||
fi
|
||||
|
||||
upstream_base_url="$(python3 - "$PACK_PATH" "$provider_id" <<'PY'
|
||||
import json, pathlib, sys
|
||||
pack_path = pathlib.Path(sys.argv[1])
|
||||
provider_id = sys.argv[2]
|
||||
provider_file = pack_path / "providers" / f"{provider_id}.json"
|
||||
provider = json.loads(provider_file.read_text(encoding='utf-8'))
|
||||
print(str(provider.get("base_url", "")).strip())
|
||||
PY
|
||||
)"
|
||||
if [[ -z "$upstream_base_url" ]]; then
|
||||
echo "missing provider base_url for $provider_id in $PACK_PATH" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
ssh_cmd() {
|
||||
local cmd="$1"
|
||||
ssh -i "$KEY" -o StrictHostKeyChecking=no "$REMOTE" "$cmd"
|
||||
@@ -454,6 +468,14 @@ ssh_cmd "curl -sS -D /tmp/chat_headers.txt -o /tmp/chat_body.json -H 'Authorizat
|
||||
ssh_cmd "cat /tmp/chat_headers.txt" > "$ART/11-chat.headers.txt"
|
||||
ssh_cmd "cat /tmp/chat_body.json" > "$ART/12-chat.body.json"
|
||||
|
||||
ssh_cmd "curl -sS -D /tmp/upstream_models_headers.txt -o /tmp/upstream_models_body.json -H 'Authorization: Bearer $upstream_key' ${upstream_base_url%/}/models"
|
||||
ssh_cmd "cat /tmp/upstream_models_headers.txt" > "$ART/17-upstream-models.headers.txt"
|
||||
ssh_cmd "cat /tmp/upstream_models_body.json" > "$ART/18-upstream-models.body.json"
|
||||
|
||||
ssh_cmd "curl -sS -D /tmp/upstream_chat_headers.txt -o /tmp/upstream_chat_body.txt -H 'Authorization: Bearer $upstream_key' -H 'Content-Type: application/json' ${upstream_base_url%/}/chat/completions -d $(printf %q "$probe_payload")"
|
||||
ssh_cmd "cat /tmp/upstream_chat_headers.txt" > "$ART/19-upstream-chat.headers.txt"
|
||||
ssh_cmd "cat /tmp/upstream_chat_body.txt" > "$ART/20-upstream-chat.body.txt"
|
||||
|
||||
crm_curl_json GET "/api/providers/$provider_id/status" > "$ART/13-provider-status.json"
|
||||
crm_curl_json GET "/api/providers/$provider_id/access/status" > "$ART/14-access-status.json"
|
||||
preview_payload="$(python3 - "$provider_id" <<'PY'
|
||||
@@ -472,17 +494,67 @@ provider_id=sys.argv[2]
|
||||
batch_id=int(sys.argv[3])
|
||||
subscription_group_id=sys.argv[4]
|
||||
expected_model=sys.argv[5]
|
||||
|
||||
def normalize_model_id(model_id: str) -> str:
|
||||
value = str(model_id or '').strip().lower()
|
||||
if not value:
|
||||
return ''
|
||||
if '/' in value:
|
||||
value = value.split('/')[-1]
|
||||
return value
|
||||
|
||||
def has_expected_model(models, expected: str) -> bool:
|
||||
normalized_expected = normalize_model_id(expected)
|
||||
if not normalized_expected:
|
||||
return False
|
||||
return any(normalize_model_id(model_id) == normalized_expected for model_id in models)
|
||||
|
||||
def status_from_headers(path: pathlib.Path) -> int:
|
||||
if not path.exists():
|
||||
return 0
|
||||
for line in path.read_text(encoding='utf-8').splitlines():
|
||||
parts = line.strip().split()
|
||||
if len(parts) >= 2 and parts[0].startswith('HTTP/'):
|
||||
try:
|
||||
return int(parts[1])
|
||||
except ValueError:
|
||||
return 0
|
||||
return 0
|
||||
|
||||
def load_json(path: pathlib.Path):
|
||||
try:
|
||||
return json.loads(path.read_text(encoding='utf-8'))
|
||||
except Exception:
|
||||
return {}
|
||||
|
||||
import_obj=json.loads((art/'03-import.body.json').read_text())
|
||||
models_obj=json.loads((art/'10-models.body.json').read_text())
|
||||
access_status=json.loads((art/'14-access-status.json').read_text())
|
||||
preview=json.loads((art/'15-access-preview.json').read_text())
|
||||
models_obj=load_json(art/'10-models.body.json')
|
||||
access_status=load_json(art/'14-access-status.json')
|
||||
preview=load_json(art/'15-access-preview.json')
|
||||
models_headers=(art/'09-models.headers.txt').read_text()
|
||||
chat_headers=(art/'11-chat.headers.txt').read_text()
|
||||
upstream_models_obj=load_json(art/'18-upstream-models.body.json')
|
||||
upstream_chat_headers=(art/'19-upstream-chat.headers.txt')
|
||||
upstream_chat_body=(art/'20-upstream-chat.body.txt').read_text(encoding='utf-8')
|
||||
models=[]
|
||||
for item in models_obj.get('data') or []:
|
||||
model_id = item.get('id')
|
||||
if isinstance(model_id, str) and model_id:
|
||||
models.append(model_id)
|
||||
upstream_models=[]
|
||||
for item in upstream_models_obj.get('data') or []:
|
||||
model_id = item.get('id')
|
||||
if isinstance(model_id, str) and model_id:
|
||||
upstream_models.append(model_id)
|
||||
host_chat_status = status_from_headers(art/'11-chat.headers.txt')
|
||||
upstream_chat_status = status_from_headers(upstream_chat_headers)
|
||||
classification = 'unknown'
|
||||
direct_has_expected_model = has_expected_model(models, expected_model)
|
||||
upstream_has_expected_model = has_expected_model(upstream_models, expected_model)
|
||||
if direct_has_expected_model and host_chat_status >= 500 and upstream_chat_status == 200:
|
||||
classification = 'host_compatibility_gap'
|
||||
elif direct_has_expected_model and upstream_chat_status == 403 and 'insufficient_user_quota' in upstream_chat_body:
|
||||
classification = 'upstream_key_quota_issue'
|
||||
summary={
|
||||
'artifact_dir': str(art),
|
||||
'provider_id': provider_id,
|
||||
@@ -491,14 +563,21 @@ summary={
|
||||
'access_status_from_import': import_obj.get('access_status'),
|
||||
'provider_status_from_import': import_obj.get('provider_status'),
|
||||
'direct_models_http200': '200 OK' in models_headers,
|
||||
'direct_models_has_expected_model': expected_model in models,
|
||||
'direct_models_has_expected_model': direct_has_expected_model,
|
||||
'direct_models': models,
|
||||
'direct_chat_http200': '200 OK' in chat_headers,
|
||||
'direct_chat_status': host_chat_status,
|
||||
'upstream_models': upstream_models,
|
||||
'upstream_models_has_expected_model': upstream_has_expected_model,
|
||||
'upstream_chat_status': upstream_chat_status,
|
||||
'completion_classification': classification,
|
||||
'latest_access_status': access_status.get('latest_access_status') or access_status.get('batch_access_status'),
|
||||
'preview_available': preview.get('available'),
|
||||
'accepted_keys_count': import_obj.get('accepted_keys_count'),
|
||||
'subscription_group_id': subscription_group_id,
|
||||
'import_group_id': (import_obj.get('group') or {}).get('id'),
|
||||
}
|
||||
print(json.dumps(summary, ensure_ascii=False))
|
||||
summary_json = json.dumps(summary, ensure_ascii=False)
|
||||
(art / '21-summary.json').write_text(summary_json, encoding='utf-8')
|
||||
print(summary_json)
|
||||
PY
|
||||
|
||||
Reference in New Issue
Block a user