-
Notifications
You must be signed in to change notification settings - Fork 2
fix(supermodel): remove GT and analysis caching — always run fresh (#714) #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1fb5a42
f09eb62
1da3a91
fe5f8fb
9021d75
20c3ca0
731cea6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,10 +4,9 @@ | |
| import hashlib | ||
| import json | ||
| import logging | ||
| import os | ||
| import sys | ||
| import tempfile | ||
| import time | ||
| from typing import Any | ||
|
|
||
| logger = logging.getLogger("mcpbr.supermodel") | ||
|
|
||
|
|
@@ -44,29 +43,19 @@ async def call_supermodel_api( | |
| with open(zip_path, "rb") as f: | ||
| zip_hash = hashlib.sha256(f.read()).hexdigest()[:12] | ||
| ep_name = endpoint_path.strip("/").replace("/", "-") | ||
| idempotency_key = f"bench:{ep_name}:{zip_hash}:v2" | ||
| idempotency_key = f"bench:{ep_name}:{zip_hash}:v3" | ||
|
|
||
| headers = [ | ||
| "-H", | ||
| "Accept: application/json", | ||
| "-H", | ||
| f"Idempotency-Key: {idempotency_key}", | ||
| ] | ||
|
|
||
| # Pass API key via curl config file to avoid exposure in process table (ps aux) | ||
| api_key_config_path: str | None = None | ||
| if api_key: | ||
| with tempfile.NamedTemporaryFile( | ||
| mode="w", suffix=".cfg", prefix="mcpbr_curl_", delete=False | ||
| ) as api_key_fd: | ||
| api_key_fd.write(f'header = "X-Api-Key: {api_key}"\n') | ||
| api_key_config_path = api_key_fd.name | ||
| os.chmod(api_key_config_path, 0o600) | ||
| headers.extend(["-H", f"X-Api-Key: {api_key}"]) | ||
|
|
||
| # Initial request with file upload | ||
| upload_cmd = ["curl", "-s", "-X", "POST", url, "-F", f"file=@{zip_path}", *headers] | ||
|
Comment on lines
54
to
58
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
python - <<'PY'
import os
import subprocess
import time
proc = subprocess.Popen(
["python", "-c", "import time; time.sleep(5)", "X-Api-Key: demo-secret"]
)
time.sleep(1)
os.system(f"ps -o command= -p {proc.pid}")
proc.terminate()
proc.wait()
PYRepository: supermodeltools/mcpbr Length of output: 85 🏁 Script executed: find src -name "api_client.py" -type fRepository: supermodeltools/mcpbr Length of output: 110 🏁 Script executed: cat -n src/mcpbr/benchmarks/supermodel/api_client.py | sed -n '45,70p'Repository: supermodeltools/mcpbr Length of output: 1082 🏁 Script executed: cat -n src/mcpbr/benchmarks/supermodel/api_client.py | sed -n '1,65p'Repository: supermodeltools/mcpbr Length of output: 2434 🏁 Script executed: cat -n src/mcpbr/benchmarks/supermodel/api_client.py | sed -n '65,100p'Repository: supermodeltools/mcpbr Length of output: 1640 🏁 Script executed: cat -n src/mcpbr/benchmarks/supermodel/api_client.py | sed -n '97,130p'Repository: supermodeltools/mcpbr Length of output: 1459 Move API key out of curl command-line arguments. Right now, the API key gets passed to curl as a Here's the simple reason why: when you call Fix options:
I'd suggest option 3 (Python HTTP client) since you're already in async context. Otherwise, option 1 (temp config file) is safer than option 2. 🤖 Prompt for AI Agents |
||
| if api_key_config_path: | ||
| upload_cmd.extend(["--config", api_key_config_path]) | ||
|
|
||
| start_time = time.time() | ||
| print( | ||
|
|
@@ -83,10 +72,7 @@ async def call_supermodel_api( | |
| if proc.returncode != 0: | ||
| raise RuntimeError(f"Supermodel API request failed: {stderr.decode()}") | ||
|
|
||
| try: | ||
| response = json.loads(stdout.decode()) | ||
| except json.JSONDecodeError as e: | ||
| raise RuntimeError(f"Non-JSON response from Supermodel API: {stdout.decode()[:500]}") from e | ||
| response = json.loads(stdout.decode()) | ||
|
|
||
| # Poll if async — use lightweight requests (1-byte dummy file instead of | ||
| # re-uploading the full zip). The API recognizes the idempotency key and | ||
|
|
@@ -102,6 +88,8 @@ async def call_supermodel_api( | |
|
|
||
| # Create poll dummy on first iteration only | ||
| if poll_dummy_path is None: | ||
| import tempfile | ||
|
|
||
| with tempfile.NamedTemporaryFile(suffix=".zip", delete=False) as poll_dummy: | ||
| poll_dummy.write(b"\n") | ||
| poll_dummy_path = poll_dummy.name | ||
|
|
@@ -116,8 +104,6 @@ async def call_supermodel_api( | |
| f"file=@{poll_dummy_path}", | ||
| *headers, | ||
| ] | ||
| if api_key_config_path: | ||
| poll_cmd.extend(["--config", api_key_config_path]) | ||
|
|
||
| retry_after = response.get("retryAfter", 10) | ||
| poll_count += 1 | ||
|
|
@@ -138,17 +124,12 @@ async def call_supermodel_api( | |
|
|
||
| if proc.returncode != 0: | ||
| raise RuntimeError(f"Supermodel API poll failed: {stderr.decode()}") | ||
| try: | ||
| response = json.loads(stdout.decode()) | ||
| except json.JSONDecodeError as e: | ||
| raise RuntimeError( | ||
| f"Non-JSON poll response from Supermodel API: {stdout.decode()[:500]}" | ||
| ) from e | ||
| response = json.loads(stdout.decode()) | ||
| finally: | ||
| if poll_dummy_path is not None: | ||
| os.unlink(poll_dummy_path) | ||
| if api_key_config_path is not None: | ||
| os.unlink(api_key_config_path) | ||
| import os as _os | ||
|
|
||
| _os.unlink(poll_dummy_path) | ||
|
|
||
| elapsed = time.time() - start_time | ||
|
|
||
|
|
@@ -161,6 +142,6 @@ async def call_supermodel_api( | |
| if isinstance(status, int) and status >= 400: | ||
| raise RuntimeError(f"Supermodel API HTTP {status}: {response.get('message', response)}") | ||
|
|
||
| api_result = response.get("result", response) | ||
| api_result: dict[str, Any] = response.get("result", response) | ||
| print(f" Supermodel API: completed in {elapsed:.1f}s", file=sys.stderr, flush=True) | ||
| return dict(api_result) | ||
| return api_result | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Document the result-semantics change too.
This PR also changes what Supermodel reports back to users:
fp_modecan now be"vs alive set", andresolvedis no longer recall-gated. That shows up in run output and result JSON, so it should have its own[Unreleased]entry alongside the cache/GT fixes.Based on learnings "Applies to CHANGELOG.md : Update CHANGELOG.md with ALL user-visible changes: new features, bug fixes, breaking changes, deprecations, security fixes, performance improvements, and CLI/configuration changes".
🤖 Prompt for AI Agents