-
Notifications
You must be signed in to change notification settings - Fork 897
chore: run ruff format across all Python node files #505
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
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 |
|---|---|---|
|
|
@@ -67,7 +67,7 @@ | |
|
|
||
| # Spatial format prompt modifiers | ||
| SPATIAL_PROMPTS = { | ||
| 'clock': '\n\nUse clock positions for spatial references (12 o\'clock = straight ahead).', | ||
| 'clock': "\n\nUse clock positions for spatial references (12 o'clock = straight ahead).", | ||
| 'relative': '\n\nUse relative directions (left, right, ahead, behind) for spatial references.', | ||
| 'both': '\n\nUse both clock positions and relative directions for spatial references.', | ||
| } | ||
|
|
@@ -98,31 +98,18 @@ def __init__(self, provider: str, connConfig: dict[str, Any], bag: dict[str, Any | |
| spatial_format = config.get('accessibility.spatialFormat', 'clock') | ||
|
|
||
| # Build system prompt with config modifiers | ||
| self._system_prompt = ( | ||
| config.get('accessibility.systemPrompt') | ||
| or config.get('systemPrompt') | ||
| or DEFAULT_SYSTEM_PROMPT | ||
| ) | ||
| self._system_prompt = config.get('accessibility.systemPrompt') or config.get('systemPrompt') or DEFAULT_SYSTEM_PROMPT | ||
| self._system_prompt += HAZARD_PROMPTS.get(hazard_priority, '') | ||
| self._system_prompt += SPATIAL_PROMPTS.get(spatial_format, '') | ||
|
|
||
| self._prompt = ( | ||
| config.get('accessibility.prompt') | ||
| or config.get('prompt') | ||
| or DEFAULT_PROMPT | ||
| ) | ||
| self._prompt = config.get('accessibility.prompt') or config.get('prompt') or DEFAULT_PROMPT | ||
|
|
||
| if not api_key: | ||
| raise ValueError( | ||
| 'Missing Google AI API key. Get one at https://aistudio.google.com/apikey' | ||
| ) | ||
| raise ValueError('Missing Google AI API key. Get one at https://aistudio.google.com/apikey') | ||
|
Contributor
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. 🧹 Nitpick | 🔵 Trivial TRY003 warnings remain on long inline Ruff is still flagging these lines; consider moving message text to named constants or a dedicated exception type to keep raises concise and consistent. Also applies to: 112-112, 189-189 🧰 Tools🪛 Ruff (0.15.7)[warning] 108-108: Avoid specifying long messages outside the exception class (TRY003) 🤖 Prompt for AI Agents |
||
|
|
||
| # Validate the API key format | ||
| if api_key.startswith('sk-'): | ||
| raise ValueError( | ||
| 'Invalid API key format. This appears to be an OpenAI key. ' | ||
| 'Please provide a Google AI API key.' | ||
| ) | ||
| raise ValueError('Invalid API key format. This appears to be an OpenAI key. Please provide a Google AI API key.') | ||
|
|
||
| try: | ||
| self._client = genai.Client(api_key=api_key) | ||
|
|
@@ -157,7 +144,7 @@ def _format_user_error(self, error_msg: str) -> str: | |
| if any(phrase in error_lower for phrase in ['invalid input', 'bad request', '400']): | ||
| return 'Invalid input. Please check your image format and prompt.' | ||
| if any(phrase in error_lower for phrase in ['model not found', 'unavailable', 'not supported']): | ||
| return f'Model \'{self._model}\' is currently unavailable. Please try a different model.' | ||
| return f"Model '{self._model}' is currently unavailable. Please try a different model." | ||
| if any(phrase in error_lower for phrase in ['timeout', 'timed out']): | ||
| return 'Request timed out. Please try again.' | ||
| if any(phrase in error_lower for phrase in ['content policy', 'safety', 'blocked']): | ||
|
|
@@ -199,9 +186,7 @@ def chat(self, question: Question) -> Answer: | |
| mime_type = header.split(':')[1].split(';')[0] | ||
| image_bytes = base64.b64decode(b64_data) | ||
| except (ValueError, IndexError, base64.binascii.Error) as e: | ||
| raise ValueError( | ||
| 'Malformed image data URL. Expected format: data:<mime>;base64,<data>' | ||
| ) from e | ||
| raise ValueError('Malformed image data URL. Expected format: data:<mime>;base64,<data>') from e | ||
|
|
||
| # Build request contents once (deterministic, no need to rebuild per retry) | ||
| contents = [ | ||
|
|
@@ -233,7 +218,7 @@ def chat(self, question: Question) -> Answer: | |
| except Exception as e: | ||
| last_error = e | ||
| if attempt < max_retries and self._shouldRetry(e): | ||
| delay = base_delay * (2 ** attempt) | ||
| delay = base_delay * (2**attempt) | ||
| time.sleep(delay) | ||
| continue | ||
| break | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -27,15 +27,10 @@ | |||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| class IInstance(IInstanceBase): | ||||||||||||||||||||||||||||||||||||||
| IGlobal: IGlobal # Reference to a global context providing recognizer functionality | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| # Default PII labels for zero-shot NER when no classifications provided | ||||||||||||||||||||||||||||||||||||||
| DEFAULT_PII_LABELS = [ | ||||||||||||||||||||||||||||||||||||||
| 'person', 'name', 'email', 'phone number', 'address', | ||||||||||||||||||||||||||||||||||||||
| 'social security number', 'credit card number', 'date of birth', | ||||||||||||||||||||||||||||||||||||||
| 'organization', 'company', 'location', 'ip address', | ||||||||||||||||||||||||||||||||||||||
| 'bank account', 'passport number', 'driver license' | ||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| DEFAULT_PII_LABELS = ['person', 'name', 'email', 'phone number', 'address', 'social security number', 'credit card number', 'date of birth', 'organization', 'company', 'location', 'ip address', 'bank account', 'passport number', 'driver license'] | ||||||||||||||||||||||||||||||||||||||
|
Contributor
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
# Verify whether DEFAULT_PII_LABELS is mutated anywhere (should return no mutation sites).
rg -n -C2 "DEFAULT_PII_LABELS\s*(\[|\=|\.append|\.extend|\.remove|\.pop|\.clear|\[.*\]\s*=)" nodes/src/nodes/anonymize/IInstance.py nodes/src/nodes/anonymizeRepository: rocketride-org/rocketride-server Length of output: 247 🏁 Script executed: # First, let me examine the file structure and context around line 32
cat -n nodes/src/nodes/anonymize/IInstance.py | head -50Repository: rocketride-org/rocketride-server Length of output: 2840 🏁 Script executed: # Search for DEFAULT_PII_LABELS usage and potential mutations with simpler, corrected patterns
rg -n "DEFAULT_PII_LABELS" nodes/src/nodes/anonymize/Repository: rocketride-org/rocketride-server Length of output: 530 🏁 Script executed: # Check for mutations via append, extend, remove, pop, clear, or direct assignment
rg -n "\.append\(|\.extend\(|\.remove\(|\.pop\(|\.clear\(" nodes/src/nodes/anonymize/IInstance.pyRepository: rocketride-org/rocketride-server Length of output: 58 🏁 Script executed: # Search the entire anonymize directory for DEFAULT_PII_LABELS mutations or reassignment
rg -n "DEFAULT_PII_LABELS" nodes/src/nodes/anonymize/ -A 2 -B 2Repository: rocketride-org/rocketride-server Length of output: 1109 🏁 Script executed: # Check if there are any attempts to modify the list through indexing or methods
rg -n "DEFAULT_PII_LABELS\[|DEFAULT_PII_LABELS\.pop|DEFAULT_PII_LABELS\.remove|DEFAULT_PII_LABELS\.append|DEFAULT_PII_LABELS\.extend|DEFAULT_PII_LABELS\.clear" nodes/src/nodes/anonymize/Repository: rocketride-org/rocketride-server Length of output: 58 Avoid mutable class-level default for Line 32 defines a mutable list at class scope; while no mutations are currently made in the codebase, accidental mutation would leak across instances. Prefer an immutable tuple constant. 🛡️ Proposed fix- DEFAULT_PII_LABELS = ['person', 'name', 'email', 'phone number', 'address', 'social security number', 'credit card number', 'date of birth', 'organization', 'company', 'location', 'ip address', 'bank account', 'passport number', 'driver license']
+ DEFAULT_PII_LABELS = (
+ 'person',
+ 'name',
+ 'email',
+ 'phone number',
+ 'address',
+ 'social security number',
+ 'credit card number',
+ 'date of birth',
+ 'organization',
+ 'company',
+ 'location',
+ 'ip address',
+ 'bank account',
+ 'passport number',
+ 'driver license',
+ )📝 Committable suggestion
Suggested change
🧰 Tools🪛 Ruff (0.15.7)[warning] 32-32: Mutable default value for class attribute (RUF012) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||
| # Current object context properties | ||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -59,7 +54,7 @@ def closing(self): | |||||||||||||||||||||||||||||||||||||
| if not self.has_classifications: | ||||||||||||||||||||||||||||||||||||||
| # No classifications received - anonymize with default PII labels | ||||||||||||||||||||||||||||||||||||||
| self.target_object_text = self.IGlobal.recognizer.process(self.target_object_text, self.DEFAULT_PII_LABELS) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| # Resume the writeText lane | ||||||||||||||||||||||||||||||||||||||
| self.instance.writeText(self.target_object_text) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -36,7 +36,7 @@ class GliNERRecognizer: | |||||
| def __init__(self, provider: str, connConfig: Dict[str, Any], bag: Dict[str, Any]): | ||||||
| """ | ||||||
| Initialize the GLiNER Recognizer. | ||||||
|
|
||||||
| Uses ai.common.models.GLiNER which automatically routes to model server | ||||||
| if --modelserver flag is present, otherwise runs locally. | ||||||
| """ | ||||||
|
|
@@ -50,7 +50,7 @@ def __init__(self, provider: str, connConfig: Dict[str, Any], bag: Dict[str, Any | |||||
| enginePath = expand('%execPath%') | ||||||
| rule_file_path = os.path.join(enginePath, 'nucleuz', 'rulePack.dat') | ||||||
| self.ruleParser = RuleParser(rule_file_path) | ||||||
|
|
||||||
| # Use ai.common.models.GLiNER - auto-detects local vs model server mode | ||||||
| self.model = GLiNER(self.model_name) | ||||||
|
|
||||||
|
|
@@ -182,34 +182,34 @@ def process_chunk(chunk_idx): | |||||
| def process(self, text: str, labels: list, existing_matches: list = None) -> str: | ||||||
| """ | ||||||
| Core anonymization method - detects entities using GLiNER and masks them. | ||||||
|
|
||||||
| Args: | ||||||
| text: The text to anonymize | ||||||
| labels: Entity labels to detect | ||||||
| existing_matches: Optional list of (offset, length) tuples from classifications | ||||||
|
|
||||||
| Returns: | ||||||
| Anonymized text with detected entities replaced by anonymize_char | ||||||
| """ | ||||||
| if not text: | ||||||
| return text | ||||||
|
|
||||||
| # Run NER prediction | ||||||
| ner_results = self.predict(text, labels) | ||||||
| ner_matches = self.convert_ner_results_to_matches(ner_results) | ||||||
|
|
||||||
| debug(f'Anonymize: Detected {len(ner_results)} entities') | ||||||
|
|
||||||
| # Combine with existing matches (from classifications) | ||||||
| all_matches = list(existing_matches or []) + ner_matches | ||||||
|
|
||||||
| if not all_matches: | ||||||
| debug('Anonymize: No entities to mask') | ||||||
| return text | ||||||
|
|
||||||
| # Sort by offset and apply masking | ||||||
| all_matches_sorted = sorted(all_matches, key=lambda x: x[0]) | ||||||
|
|
||||||
| return _anonymize(text, all_matches_sorted, self.anonymize_char) | ||||||
|
|
||||||
| def handleClassifications(self, classifications: dict, target_object_text: str, classificationPolicy: any, classificationRules: any): | ||||||
|
|
@@ -234,9 +234,6 @@ def handleClassifications(self, classifications: dict, target_object_text: str, | |||||
| labels = self.ruleParser.get_rules_names(unique_id_refs) + rules | ||||||
|
|
||||||
| # Extract existing matches from classifications (offset, length tuples) | ||||||
| existing_matches = list( | ||||||
| (m['offset'], m['length']) | ||||||
| for m in ((m.get('location', {}).get('inChars') or m) for m in text_matches) | ||||||
| ) | ||||||
| existing_matches = list((m['offset'], m['length']) for m in ((m.get('location', {}).get('inChars') or m) for m in text_matches)) | ||||||
|
Contributor
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. 🧹 Nitpick | 🔵 Trivial 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify the exact pattern and nearby context for C400-style constructions.
rg -n -C2 "existing_matches\s*=\s*list\(" nodes/src/nodes/anonymize/glinerRecognizer.pyRepository: rocketride-org/rocketride-server Length of output: 388 Rewrite Use ♻️ Proposed cleanup- existing_matches = list((m['offset'], m['length']) for m in ((m.get('location', {}).get('inChars') or m) for m in text_matches))
+ existing_matches = [(m['offset'], m['length']) for m in ((m.get('location', {}).get('inChars') or m) for m in text_matches)]📝 Committable suggestion
Suggested change
🧰 Tools🪛 Ruff (0.15.7)[warning] 237-237: Unnecessary generator (rewrite as a list comprehension) Rewrite as a list comprehension (C400) 🤖 Prompt for AI Agents |
||||||
|
|
||||||
| return self.process(target_object_text, labels, existing_matches) | ||||||
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.
🛠️ Refactor suggestion | 🟠 Major
Use single quotes for regular string literals in
nodes/**/*.py.These two updated literals switched to double quotes and now diverge from the node-level quote convention.
Proposed quote-style fix
Also applies to: 147-147
🤖 Prompt for AI Agents