From 5baa0f9a05846e38beac6b9bbd2865d1292eadf7 Mon Sep 17 00:00:00 2001 From: KTanmay1 Date: Thu, 13 Aug 2026 17:55:45 +0530 Subject: [PATCH] Do not log or persist API credentials; allow endpoint override The agent currently writes the API key to stdout on every request and stores the live `Authorization: Bearer ` header in conversation_logs/*.json, which is the directory users attach to bug reports. It also hardcodes the API endpoint, so pointing the agent at a different provider requires editing source. - Log only the last four characters of the key. - Redact the Authorization header before writing conversation logs. - Read the endpoint from REPOTRANSBENCH_BASE_URL, defaulting to the current value so existing setups are unaffected. - Read keys from REPOTRANSBENCH_API_KEY (comma-separated) when set, otherwise from API_KEY.txt as before. - Raise a clear error when no key is configured. A blank or malformed API_KEY.txt previously failed with IndexError from line.split()[1]. No change to agent behaviour, prompts, or scoring. --- RepoTransAgent/generator.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/RepoTransAgent/generator.py b/RepoTransAgent/generator.py index 4570fc2..78fe6da 100644 --- a/RepoTransAgent/generator.py +++ b/RepoTransAgent/generator.py @@ -32,9 +32,19 @@ def __init__(self, args, logger=None, system_prompt='', config_file="API_KEY.txt self.init_conversation() def load_config(self): - with open(f'RepoTransAgent/{self.config_file}', encoding='utf-8') as f: - api_keys = f.readlines() - api_keys = [line.split()[1].strip() for line in api_keys] + # Keys may come from the environment (REPOTRANSBENCH_API_KEY, comma-separated + # for rotation) or, as before, from API_KEY.txt. + env_keys = os.environ.get('REPOTRANSBENCH_API_KEY', '') + if env_keys: + api_keys = [k.strip() for k in env_keys.split(',') if k.strip()] + else: + with open(f'RepoTransAgent/{self.config_file}', encoding='utf-8') as f: + api_keys = [line.split()[1].strip() for line in f if len(line.split()) > 1] + if not api_keys: + raise RuntimeError( + f'No API key found. Set REPOTRANSBENCH_API_KEY, or add lines of the form ' + f'" " to RepoTransAgent/{self.config_file}.' + ) self.api_keys = cycle(api_keys) self.api_key = next(self.api_keys) @@ -50,6 +60,9 @@ def load_config(self): # self.base_url = 'https://api.agicto.cn' # self.base_url = 'https://www.chataiapi.com' # self.base_url = 'https://claude.aisonnet.org' + # The endpoint above is a third-party API gateway. Allow it to be overridden + # so users can point the agent at their own provider without editing source. + self.base_url = os.environ.get('REPOTRANSBENCH_BASE_URL', self.base_url).rstrip('/') self.log_path = "conversation_logs/logs.json" def init_conversation(self, repo_path=None): @@ -90,7 +103,7 @@ def get_response(self, repo_name, history_conversation=None): retry_cnt = 0 while True: try: - self.logger.info(f"Using key: {self.api_key}") + self.logger.info(f"Using key: ...{self.api_key[-4:]}") self.logger.info(f"Using base url: {self.base_url}") headers = { 'Accept': 'application/json', @@ -154,8 +167,14 @@ def record_conversation(self, headers, model_name, messages, response, repo_name if repo_name: log_path = f'conversation_logs/{repo_name}.json' + # conversation_logs/*.json is what users attach to bug reports, so the + # Authorization header must not be written to it verbatim. + safe_headers = dict(headers) + if 'Authorization' in safe_headers: + safe_headers['Authorization'] = 'Bearer ' + conversation_data = { - "headers": headers, + "headers": safe_headers, "model_name": model_name, "messages": messages, "response": response,