Skip to content

feat(nodes): add Gmail tool node (RR-1055)#1333

Closed
joshuadarron wants to merge 4 commits into
developfrom
feat/RR-1055-tool-gmail
Closed

feat(nodes): add Gmail tool node (RR-1055)#1333
joshuadarron wants to merge 4 commits into
developfrom
feat/RR-1055-tool-gmail

Conversation

@joshuadarron

@joshuadarron joshuadarron commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add tool_gmail node exposing the Gmail v1 API as agent tools: read/search/organize mail, manage labels and drafts, send (incl. in-thread replies), and gated permanent delete.
  • Add Gmail full access tier + allowHardDelete gate to the shared Google access/scope resolver; hard-delete requires both full tier and the gate.
  • Fix shared-ui social login buttons to render their label instead of a raw i18n key, with a literal fallback when i18n is unset.

Type

feature

Testing

  • Tests added or updated
  • Tested locally
  • ./builder test passes

Checklist

  • Commit messages follow conventional commits
  • No secrets or credentials included
  • Wiki updated (if applicable)
  • Breaking changes documented (if applicable)

Related Issues

Closes RR-1055

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Gmail agent tool enabling message/thread management, label organization, draft creation, and email sending with optional permanent deletion (gated by elevated permissions).
    • Introduced "full" access tier for Gmail with destructive operation controls via explicit permission flags.
  • Style

    • Improved internationalization handling in social login buttons with fallback text rendering.

joshuadarron and others added 4 commits June 5, 2026 11:00
… (RR-1055)

Extends the GMAIL spec so the Gmail node can support permanent delete: a
'full' tier granting https://mail.google.com/ and the allowHardDelete flag
that gates it. can_write stays scope-derived. Prereq for tool_gmail.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Full Gmail v1 surface as agent tools, modeled on tool_github and gated by the
shared GMAIL resolver:

- Reads/sync: message_list/get/search, thread_get/list, label_list,
  draft_list/get, attachment_get, history_list.
- Organize (write tier): message_modify, message_batch_modify, label_apply/
  remove/create/update/delete. Read-state via the UNREAD label.
- Write: message_send (reply-in-thread sets In-Reply-To/References),
  message_trash/untrash, draft_create/update/send/delete. Send requires the
  send or full tier.
- Permanent delete (gated): message_delete, messages_batchDelete — require
  allowHardDelete + the full tier; explicit id lists only, capped at 1000.

Auth branches on google.authType (service account w/ domain delegation, or
user OAuth). Outputs are cleaned shapes, not raw API JSON. Adds a Google SDK
mock for ROCKETRIDE_MOCK and unit tests covering each function, gating,
reply threading, batch caps, and the services.json field contract.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…-1055)

The Google/Microsoft/Slack login button widgets rendered the raw key
(e.g. ADDSOURCE.FORMSTEP.LOGINWITHGOOGLEBUTTON) — uppercased by MUI and
overflowing — when the addSource.* namespace isn't loaded (as in the VS Code
config panel, where the Gmail node first surfaced it). Add a defaultValue to
each t() so the label is correct regardless of i18n state, and set
textTransform:'none' so it renders in sentence case without clipping.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…nset

defaultValue is ignored because no i18next instance is initialized in the
webview hosts — t() returns the raw key. Detect the key echo and substitute a
literal ('Login with Google'/Microsoft/Slack, 'Authenticated') so the buttons
never render a raw i18n key. Supersedes the prior defaultValue attempt.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions github-actions Bot added docs Documentation module:nodes Python pipeline nodes module:ui Chat UI and Dropper UI labels Jun 20, 2026
@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a new tool_gmail agent-tool node exposing Gmail v1 API operations (read, organize, label, draft, send, hard-delete) with service-account and user-OAuth authentication. Extends the shared Google access spec with a full tier and allowHardDelete gate. Fixes i18n fallback behavior on Google, Microsoft, and Slack login buttons.

Changes

Gmail Tool Node

Layer / File(s) Summary
GMAIL AccessSpec: full tier and allowHardDelete flag
nodes/src/nodes/core/google_access.py, nodes/test/core/test_google_access.py
Adds _GMAIL_FULL constant, a full access tier granting https://mail.google.com/ scope, and an allowHardDelete flag gate to the GMAIL AccessSpec. Tests updated to assert the new flag and full-tier can_write.
gmail_client: credentials, service construction, MIME, and response cleaners
nodes/src/nodes/tool_gmail/gmail_client.py, nodes/src/nodes/tool_gmail/requirements.txt
New module with build_service (service-account and user-OAuth), execute wrapper, build_raw_message for RFC822 MIME, and clean_* normalizers for all Gmail API response shapes. Declares four Google Python dependencies.
IGlobal: lifecycle and config validation
nodes/src/nodes/tool_gmail/IGlobal.py, nodes/src/nodes/tool_gmail/__init__.py
IGlobal resolves access tier and builds the Gmail service in beginGlobal, emits misconfiguration warnings in validateConfig, and clears shared state in endGlobal. Package __init__.py exports IGlobal and IInstance.
IInstance: all Gmail tool methods and access gating
nodes/src/nodes/tool_gmail/IInstance.py, nodes/src/nodes/tool_gmail/services.json, nodes/src/nodes/tool_gmail/README.md
All 26+ agent-callable tool methods across message, label, thread, draft, send, trash, attachment, history, and hard-delete categories. Write/send/full scope and allowHardDelete gating enforced per operation. services.json declares access enum and hard-delete field; README documents tiers, tools, and parameters.
Tests: mock SDK, FakeGmail, and full suite
nodes/test/mocks/google/..., nodes/test/mocks/googleapiclient/..., nodes/test/tool_gmail/test_gmail.py
Mock google.oauth2 and googleapiclient.discovery modules with canned fluent-chain responses. FakeGmail test double and full pytest suite covering read/write/send/hard-delete gating, reply-threading headers, batch validation, services.json contract, and SDK integration.

Login Button i18n Fallback Fix

Layer / File(s) Summary
Google/Microsoft/Slack login buttons: i18n fallback and textTransform
packages/shared-ui/src/components/canvas/components/rjsf-widgets/social-buttons/LoginWithGoogleButton.tsx, ...LoginWithMicrosoftButton.tsx, ...LoginWithSlackButton.tsx
Adds a label(key, fallback) helper to all three components that falls back to a literal string when t() echoes the raw key. All three buttons also gain textTransform: 'none' on the MUI Button sx prop.

Sequence Diagram(s)

sequenceDiagram
  participant Agent
  participant IInstance
  participant gmail_client
  participant GmailAPI

  Agent->>IInstance: message_send(args)
  IInstance->>IInstance: _require_write() + _require_send()
  alt threadId provided
    IInstance->>gmail_client: execute(threads.get metadata)
    gmail_client->>GmailAPI: users.threads.get(threadId, format=metadata)
    GmailAPI-->>gmail_client: thread with message headers
    gmail_client-->>IInstance: In-Reply-To, References headers
  end
  IInstance->>gmail_client: build_raw_message(to, subject, body, in_reply_to, references)
  gmail_client-->>IInstance: base64url raw MIME
  IInstance->>gmail_client: execute(messages.send(raw, threadId))
  gmail_client->>GmailAPI: users.messages.send(userId=me, body)
  GmailAPI-->>gmail_client: sent message
  gmail_client-->>IInstance: cleaned message dict
  IInstance-->>Agent: result
Loading
sequenceDiagram
  participant Agent
  participant IInstance
  participant gmail_client
  participant GmailAPI

  Agent->>IInstance: message_delete(args)
  IInstance->>IInstance: _require_hard_delete()
  Note over IInstance: checks allowHardDelete flag AND full tier
  IInstance->>gmail_client: execute(messages.delete(messageId))
  gmail_client->>GmailAPI: users.messages.delete(userId=me, id=messageId)
  GmailAPI-->>gmail_client: 204 empty response
  gmail_client-->>IInstance: {}
  IInstance-->>Agent: {deleted: messageId}
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

  • rocketride-org/rocketride-server#1074: The google_access.py changes in this PR (adding the full tier and allowHardDelete gate) extend the shared resolve_google_access/AccessSpec infrastructure introduced in that PR.

Suggested labels

module:nodes, module:ui

Suggested reviewers

  • jmaionchi
  • stepmikhaylov
  • Rod-Christensen
  • asclearuc

Poem

🐰 Hop hop, the mailbox is open at last,
With full tiers and hard-delete safely gated fast,
Each thread and each draft now cleaned up with care,
i18n won't echo raw keys through the air,
The rabbit sends messages — t() won't despair! ✉️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.20% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(nodes): add Gmail tool node (RR-1055)' clearly and concisely summarizes the main change—introducing a new Gmail tool node to the platform.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/RR-1055-tool-gmail

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown
🤖 Internal: Discord sync marker

Auto-managed by the Discord notification workflow. Stores the linked Discord message ID. Do not edit or delete.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@nodes/src/nodes/tool_gmail/IInstance.py`:
- Around line 93-101: The _id_list method validates that IDs contain only
non-empty trimmed strings by checking i.strip() in the validation condition, but
returns the original unstripped ids list. This allows whitespace-padded message
IDs to pass validation and then fail downstream in Gmail API calls. Modify the
return statement to strip whitespace from each ID in the list before returning,
ensuring that the returned IDs match what was validated.

In `@nodes/src/nodes/tool_gmail/requirements.txt`:
- Around line 1-4: The requirements.txt file for the tool_gmail node contains
unpinned dependencies (google-api-python-client, google-auth,
google-auth-oauthlib, google-auth-httplib2) which allow vulnerable transitive
versions of idna and protobuf to be installed. Pin these dependencies to tested
versions that resolve the security vulnerabilities: add version constraints to
require idna>=3.15 to fix CVE-2024-3651, and require protobuf>=4.25.8 (or
>=5.29.5 or >=6.31.1 depending on your base version) to fix CVE-2025-4565.
Update each package line in requirements.txt to include the appropriate version
specifier using the format package-name>=version.

In
`@packages/shared-ui/src/components/canvas/components/rjsf-widgets/social-buttons/LoginWithGoogleButton.tsx`:
- Around line 100-108: The label helper function in LoginWithGoogleButton that
handles i18n fallback logic (the function that takes a key and fallback string
and returns the resolved translation or the fallback) is duplicated across
multiple social login button components (Google, Microsoft, Slack). Extract this
label function into a shared utility file or custom hook that can be imported by
all social login button components, then replace the duplicate implementations
with imports from this shared location to ensure consistent fallback behavior
across all providers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: fa6ae1e6-9e44-4f3c-8159-b8db4c6b271a

📥 Commits

Reviewing files that changed from the base of the PR and between e1b4da7 and a94ece2.

⛔ Files ignored due to path filters (1)
  • nodes/src/nodes/tool_gmail/gmail.svg is excluded by !**/*.svg
📒 Files selected for processing (19)
  • nodes/src/nodes/core/google_access.py
  • nodes/src/nodes/tool_gmail/IGlobal.py
  • nodes/src/nodes/tool_gmail/IInstance.py
  • nodes/src/nodes/tool_gmail/README.md
  • nodes/src/nodes/tool_gmail/__init__.py
  • nodes/src/nodes/tool_gmail/gmail_client.py
  • nodes/src/nodes/tool_gmail/requirements.txt
  • nodes/src/nodes/tool_gmail/services.json
  • nodes/test/core/test_google_access.py
  • nodes/test/mocks/google/oauth2/__init__.py
  • nodes/test/mocks/google/oauth2/credentials.py
  • nodes/test/mocks/google/oauth2/service_account.py
  • nodes/test/mocks/googleapiclient/__init__.py
  • nodes/test/mocks/googleapiclient/discovery.py
  • nodes/test/tool_gmail/__init__.py
  • nodes/test/tool_gmail/test_gmail.py
  • packages/shared-ui/src/components/canvas/components/rjsf-widgets/social-buttons/LoginWithGoogleButton.tsx
  • packages/shared-ui/src/components/canvas/components/rjsf-widgets/social-buttons/LoginWithMicrosoftButton.tsx
  • packages/shared-ui/src/components/canvas/components/rjsf-widgets/social-buttons/LoginWithSlackButton.tsx

Comment on lines +93 to +101
def _id_list(args: dict, key: str, op: str) -> list[str]:
ids = args.get(key)
if not isinstance(ids, list) or not ids:
raise ValueError(f'{op}: "{key}" must be a non-empty list of message ids')
if not all(isinstance(i, str) and i.strip() for i in ids):
raise ValueError(f'{op}: "{key}" must contain only message-id strings')
if len(ids) > MAX_BATCH:
raise ValueError(f'{op}: at most {MAX_BATCH} ids per call (got {len(ids)})')
return ids

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Trim IDs before returning from _id_list.

Validation uses i.strip() but the method returns original values, so whitespace-padded IDs pass checks and then fail downstream Gmail calls.

Suggested fix
     def _id_list(args: dict, key: str, op: str) -> list[str]:
         ids = args.get(key)
         if not isinstance(ids, list) or not ids:
             raise ValueError(f'{op}: "{key}" must be a non-empty list of message ids')
         if not all(isinstance(i, str) and i.strip() for i in ids):
             raise ValueError(f'{op}: "{key}" must contain only message-id strings')
+        ids = [i.strip() for i in ids]
         if len(ids) > MAX_BATCH:
             raise ValueError(f'{op}: at most {MAX_BATCH} ids per call (got {len(ids)})')
         return ids
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@nodes/src/nodes/tool_gmail/IInstance.py` around lines 93 - 101, The _id_list
method validates that IDs contain only non-empty trimmed strings by checking
i.strip() in the validation condition, but returns the original unstripped ids
list. This allows whitespace-padded message IDs to pass validation and then fail
downstream in Gmail API calls. Modify the return statement to strip whitespace
from each ID in the list before returning, ensuring that the returned IDs match
what was validated.

Comment on lines +1 to +4
google-api-python-client
google-auth
google-auth-oauthlib
google-auth-httplib2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify current resolved vulnerabilities for this requirements file
python -m pip install -q pip-audit
pip-audit -r nodes/src/nodes/tool_gmail/requirements.txt

# Inspect available versions for flagged transitives
python -m pip index versions idna | sed -n '1,25p'
python -m pip index versions protobuf | sed -n '1,25p'

Repository: rocketride-org/rocketride-server

Length of output: 556


🏁 Script executed:

cat -n nodes/src/nodes/tool_gmail/requirements.txt

Repository: rocketride-org/rocketride-server

Length of output: 183


🌐 Web query:

google-auth google-api-python-client security vulnerabilities CVE 2024 2025

💡 Result:

Summary (CVE-focused, 2024–2025): 1) google-auth and google-api-python-client do not appear to have widely reported, product-specific CVEs in 2024–2025 in the sources found here. - For google-api-python-client, the only CVE-like item surfaced in results was CVE-2023-34298, which is outside your requested 2024–2025 window and is not clearly tied to the upstream Google library’s security fixes (it appears in a third-party issue tracker context) [1]. - For google-auth, the results found a CVE entry (CVE-2024-26130) for “product=google-auth” via a third-party CVE tracker, but the snippet describes a NULL pointer dereference in cryptography (not a direct, google-auth logic flaw), and the tracker indicates the fix is “resolved in cryptography … 42.0.4” [2]. 2) google-api-python-client / google-auth-library-python have frequent changes (mostly bug/security related) in their official changelogs, but the changelog extracts shown do not enumerate CVE IDs tied specifically to 2024–2025 for these libraries [3][4][5][6]. What you should do in practice (grounded guidance from the sources): - Treat underlying dependencies as the most likely CVE source for this ecosystem. Example: CVE-2024-26130 is reported in a tracker as involving “product=google-auth” but the technical description attributes the bug to cryptography’s PKCS#12 serialization behavior and says it’s resolved in cryptography 42.0.4 [2]. - Keep google-auth-library-python and google-api-python-client updated to the latest patch releases; their projects release frequently and are explicitly positioned as maintained/with security issue handling [7][8]. - Use your own dependency-CVE tooling (SCA) against your exact installed versions; one result for google-api-python-client@2.197.0 showed “No known vulnerabilities detected” by that scanner at scan time, underscoring that the answer is version-dependent [9]. References found in this research (representative): - CVE-2024-26130 tracker entry describing a cryptography NULL pointer dereference (resolved in cryptography 42.0.4) [2]. - Official google-auth-library-python changelog activity in 2024–2025 timeframe (no CVE IDs visible in the provided excerpts) [3][4]. - Official google-api-python-client repository status/maintenance and frequent releases [7][8]. - An external listing for google-api-python-client@2.197.0 reporting no known vulnerabilities at scan time [9].

Citations:


🌐 Web query:

idna protobuf security vulnerabilities known issues 2024 2025

💡 Result:

In 2024 and 2025, security vulnerabilities were identified in both the Protocol Buffers (protobuf) library and libraries handling Internationalized Domain Names in Applications (IDNA). These issues primarily involve Denial of Service (DoS) and potential logic flaws. Protocol Buffers (protobuf) Vulnerabilities: - CVE-2025-4565: A high-severity DoS vulnerability in the protobuf-python pure-Python backend. Parsing untrusted data containing excessive recursive groups, recursive messages, or SGROUP tags can exceed the Python recursion limit, leading to a crash [1][2]. It affects versions prior to 4.25.8, 5.29.5, and 6.31.1 [1]. - CVE-2024-7254: A high-severity DoS vulnerability in protobuf-java, protobuf-javalite, and protobuf-kotlin. Similar to the Python issue, parsing nested groups as unknown fields, or against map fields, can cause unbounded recursion and stack overflow [3][4]. This affects versions prior to 3.25.5, 4.27.5, and 4.28.2 [3]. - CVE-2024-2410: A critical-severity Use-After-Free (UAF) vulnerability in the C++ implementation of protobuf. It occurs in the JsonToBinaryStream function when parsing JSON from a stream split into specific chunks, potentially leading to arbitrary code execution or crash [5]. It affects versions 4.22.0 through 4.24.x [5]. IDNA Library Vulnerabilities: - Resource Consumption/DoS: - CVE-2024-3651: Identified in the kjd/idna Python library, where specially crafted inputs to idna.encode caused significant resource consumption due to quadratic complexity [6][7]. - CVE-2026-45409: A follow-up issue involving the same kjd/idna library, where the original fix for CVE-2024-3651 could be bypassed using specific payloads, allowing attackers to trigger long processing times [8]. Users are advised to use version 3.15 or later [8]. - Logic/Equivalence Vulnerabilities: - RUSTSEC-2024-0421 (CVE-2024-12224): Found in the Rust idna crate (used by Servo's rust-url). The library accepted Punycode labels that did not produce non-ASCII output, allowing ASCII labels to be masked as punycode. This could lead to host name confusion or privilege escalation in applications relying on host name comparisons [9][10][11]. This was fixed in version 1.0.3 [9][11].

Citations:


Pin Gmail node dependencies to prevent vulnerable transitive versions.

These packages are unpinned. Transitive dependencies idna and protobuf have known security vulnerabilities (CVE-2024-3651 in idna, CVE-2025-4565 in protobuf-python). Lock tested versions so installs are reproducible and auditable. At minimum:

  • Require idna>=3.15 (fixes CVE-2024-3651 and CVE-2026-45409)
  • Require protobuf>=4.25.8 (or >=5.29.5 or >=6.31.1 depending on your base version)
🧰 Tools
🪛 OSV Scanner (2.3.8)

[MEDIUM] 1-1: idna 3.9.0: undefined

(PYSEC-2026-215)


[MEDIUM] 1-1: idna 3.9.0: Internationalized Domain Names in Applications (IDNA): Specially crafted inputs to idna.encode() can bypass CVE-2024-3651 fix

(GHSA-65pc-fj4g-8rjx)


[HIGH] 1-1: protobuf 4.25.9: protobuf affected by a JSON recursion depth bypass

(GHSA-7gcm-g887-7qv7)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@nodes/src/nodes/tool_gmail/requirements.txt` around lines 1 - 4, The
requirements.txt file for the tool_gmail node contains unpinned dependencies
(google-api-python-client, google-auth, google-auth-oauthlib,
google-auth-httplib2) which allow vulnerable transitive versions of idna and
protobuf to be installed. Pin these dependencies to tested versions that resolve
the security vulnerabilities: add version constraints to require idna>=3.15 to
fix CVE-2024-3651, and require protobuf>=4.25.8 (or >=5.29.5 or >=6.31.1
depending on your base version) to fix CVE-2025-4565. Update each package line
in requirements.txt to include the appropriate version specifier using the
format package-name>=version.

Source: Linters/SAST tools

Comment on lines +100 to +108
// i18n is not initialized in every host (e.g. the VS Code webview). When a key
// doesn't resolve, t() returns the key itself — fall back to a literal so the
// button never shows a raw key.
const label = (key: string, fallback: string): string => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const value = t(key as any) as string;
return value && value !== key ? value : fallback;
};
const text = authenticated ? label('addSource.formStep.authenticated', 'Authenticated') : label('addSource.formStep.loginWithGoogleButton', 'Login with Google');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Consolidate duplicated i18n fallback helper across social login buttons.

The same label(key, fallback) logic is now repeated in Google/Microsoft/Slack buttons. Extracting it into a shared utility/hook will reduce drift and keep fallback behavior consistent across providers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/shared-ui/src/components/canvas/components/rjsf-widgets/social-buttons/LoginWithGoogleButton.tsx`
around lines 100 - 108, The label helper function in LoginWithGoogleButton that
handles i18n fallback logic (the function that takes a key and fallback string
and returns the resolved translation or the fallback) is duplicated across
multiple social login button components (Google, Microsoft, Slack). Extract this
label function into a shared utility file or custom hook that can be imported by
all social login button components, then replace the duplicate implementations
with imports from this shared location to ensure consistent fallback behavior
across all providers.

@joshuadarron

Copy link
Copy Markdown
Collaborator Author

Closing in favour of a consolidated PR (#1334) that includes this feature plus the Google user-OAuth broker wiring (RR-1142) and fixes discovered during integration testing (OAuth scope forwarding, agent_langchain JSON parser).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation module:nodes Python pipeline nodes module:ui Chat UI and Dropper UI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant