Complete cloud provider patch MVP

This commit is contained in:
thanhnv
2026-07-06 12:32:54 +09:00
parent c7a1c743cb
commit d0bde2a8b3
8 changed files with 168 additions and 24 deletions
@@ -156,15 +156,42 @@ def call_openai(model_name, prompt, role):
except Exception as exc: # honest non-zero, no fake success
fail(f"backend_unreachable {type(exc).__name__}: {str(exc)[:120]}")
latency_ms = int((time.time() - t0) * 1000)
usage = payload.get("usage", {})
text, input_tokens, output_tokens = parse_openai_payload(payload)
return {
"text": (payload["choices"][0]["message"]["content"] or "").strip(),
"input_tokens": int(usage.get("prompt_tokens", 0)),
"output_tokens": int(usage.get("completion_tokens", 0)),
"text": text,
"input_tokens": input_tokens,
"output_tokens": output_tokens,
"latency_ms": latency_ms,
}
def parse_openai_payload(payload):
try:
text = (payload["choices"][0]["message"]["content"] or "").strip()
usage = payload["usage"]
input_tokens = int(usage["prompt_tokens"])
output_tokens = int(usage["completion_tokens"])
except (KeyError, IndexError, TypeError, ValueError) as exc:
fail(f"provider_usage_invalid openai {type(exc).__name__}: {str(exc)[:80]}")
return text, input_tokens, output_tokens
def parse_anthropic_payload(payload):
try:
content = payload["content"]
if not isinstance(content, list):
raise TypeError("content is not a list")
text = "".join(
b.get("text", "") for b in content if isinstance(b, dict) and b.get("type") == "text"
).strip()
usage = payload["usage"]
input_tokens = int(usage["input_tokens"])
output_tokens = int(usage["output_tokens"])
except (KeyError, TypeError, ValueError) as exc:
fail(f"provider_usage_invalid anthropic {type(exc).__name__}: {str(exc)[:80]}")
return text, input_tokens, output_tokens
def call_anthropic(model_name, prompt, role):
# Endpoint hard-pinned to the allowlisted host (no env override). NOTE: on
# current Claude models (Opus 4.8/4.7, Sonnet 5, ...) `temperature`/`top_p`
@@ -197,20 +224,14 @@ def call_anthropic(model_name, prompt, role):
except Exception as exc: # honest non-zero, no fake success
fail(f"backend_unreachable {type(exc).__name__}: {str(exc)[:120]}")
latency_ms = int((time.time() - t0) * 1000)
# content is a list of blocks; concatenate text blocks. A safety refusal
# (stop_reason=="refusal") yields empty text -> extract_verdict fails closed.
text = "".join(
b.get("text", "") for b in payload.get("content", []) if b.get("type") == "text"
).strip()
usage = payload.get("usage", {})
text, input_tokens, output_tokens = parse_anthropic_payload(payload)
return {
"text": text,
"input_tokens": int(usage.get("input_tokens", 0)),
"output_tokens": int(usage.get("output_tokens", 0)),
"input_tokens": input_tokens,
"output_tokens": output_tokens,
"latency_ms": latency_ms,
}
def main():
ap = argparse.ArgumentParser()
ap.add_argument("prompt_file")