Complete cloud provider patch MVP
This commit is contained in:
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user