Skip to content

feat(handoff): add skill-gated handoff action, access control gating, and OAuth expiry fixes - #252

Open
Tharickv75 wants to merge 31 commits into
devfrom
dev-tj
Open

Tharickv75 wants to merge 31 commits into
devfrom
dev-tj

Conversation

@Tharickv75

Copy link
Copy Markdown
Contributor

Description

Summary

This pull request introduces the new skill-gated handoff capability (jvagent/handoff_action), skill access control filtering, and improvements to Google OAuth credential handling and lead generation profile persistence.

Key updates include:

  • Skill-Gated Handoff Action (jvagent/handoff_action): Adds human-support capability tools (handoff__direct_contact, handoff__notify, handoff__staff_inbox, and handoff__resolve) supported by the jvagent/skills/handoff library skill. Enables single staff random routing across WhatsApp/email channels, pending question tracking, and automatic PageIndex Q&A ingestion to handoff.md.
  • Skill Identity Gating: Adds support for access-action and allowed-groups/denied-groups in skill frontmatter to selectively hide or reveal skills in the catalog based on AccessControlAction.user_groups.
  • Google MCP/OAuth Fixes: Normalized OAuth expiry parsing in GoogleAction to properly handle ISO string formats and avoid ValueError during token refresh, alongside fixing service binding retention.
  • LeadGen Bug Fix: Fixed an issue preventing the lead profile from being overwritten by section updates.
  • Documentation & CI: Added README.md for handoff_action, updated actions catalog and changelog, and updated Dockerfiles/workflows for release versioning (0.1.8rc20-dev1).

Type of change

  • Bug fix (non-breaking)
  • New feature (non-breaking)
  • Breaking change
  • Documentation
  • Chore / tooling / CI

Checklist

  • I read CONTRIBUTING.md and (for subsystem work) the local AGENTS.md.
  • pre-commit run --all-files passes.
  • pytest tests/ passes; I added/updated tests for new behavior.
  • Bug fixes cite file:line in the description.
  • Docs / CHANGELOG.md updated where relevant (entry under [Unreleased]).
  • No ADR was modified in place (changes of decision are written as a new, superseding ADR).

Tharickv75 and others added 15 commits September 29, 2026 11:16
…n node

Scope the unique user index to LeadProfile and resolve the record by user_node_id so a section save cannot wipe the anchor row.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ce a refresh

Store the access-token expiry from the code exchange and normalize it to the naive-UTC form google-auth can parse.

Co-authored-by: Cursor <cursoragent@cursor.com>
Let a skill declare access-action plus allowed or denied groups so the catalog fails closed when the visitor is not in the right group.

Co-authored-by: Cursor <cursoragent@cursor.com>
Give agents contact, notify, and staff Q&A tools behind the handoff skills without changing the existing handoff interact action.

Co-authored-by: Cursor <cursoragent@cursor.com>
…tools

Updated docstrings for `handoff__contact_details` and `handoff__staff_lookup` to specify their intended use cases. Enhanced the SKILL.md documentation to emphasize that contact details should only be provided upon explicit request, while any unanswerable questions should be directed to staff lookup. This improves clarity for developers and users regarding the functionality of the handoff tools.
…copes

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Clarified usage instructions in `leadgen` and `handoff` skills documentation. Updated `leadgen__retrieve` to specify it should be called mid-conversation and not at the start of a turn. Removed unnecessary references to `extends` in handoff skill files. Adjusted logging level for skill loading in the registry to debug for better traceability.
@Tharickv75 Tharickv75 self-assigned this Sep 30, 2026
@Tharickv75
Tharickv75 requested a review from eldonm as a code owner September 30, 2026 20:41
Tharickv75 and others added 4 commits October 5, 2026 08:31
Co-authored-by: Cursor <cursoragent@cursor.com>
…e interact action

This commit refactors the handoff action by consolidating its functionality into a single action mode, allowing for clearer management of human support interactions. The `handoff_interact_action` has been removed, and its features have been integrated into the main `handoff_action`. Additionally, new methods for tool access control have been introduced, enhancing the permission handling for tools based on user roles. Documentation has been updated to reflect these changes and clarify the usage of the handoff tools.
This commit updates the handoff action to improve the handling of group interactions and streamline the messaging process. The `handoff_intro` and `consult_close` messages have been revised for clarity. New utility functions for managing WhatsApp group IDs and participant phone numbers have been added, enhancing the ability to process group messages. Additionally, the documentation has been updated to reflect these changes, ensuring better guidance for developers on the usage of the handoff tools.
This commit refines the `handoff` action by removing the `handoff__pending_questions` tool and integrating its functionality into the staff turn parameter. The `consult` mode now directly injects current unanswered questions into the orchestration prompt, simplifying the staff's response process. Documentation has been updated to reflect these changes, ensuring clarity on the new parameter structure and its usage in staff interactions.

@eldonm eldonm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed revision b1048b09c4206bc16c17fafb8ea564ee1df2e732 against dev. I found six actionable issues: four P1 authorization/privacy/data-preservation problems and two P2 queue/delivery reliability problems, detailed inline. I recommend addressing these before merging.

Validation: the existing affected regression slices passed (1,003 passed, one skipped across orchestrator, access control, leadgen, WhatsApp, Google, MCP OAuth, and tool-schema tests; the separate handoff/new WhatsApp slice also passed). Six focused failure-injection/integration reproductions fail on this revision and substantiate the inline findings. External messaging and provider calls were mocked in those reproductions.

Comment thread jvagent/action/orchestrator/orchestrator_interact_action.py Outdated
Comment thread jvagent/action/orchestrator/tools.py Outdated
Comment thread jvagent/action/handoff_action/handoff_action.py
Comment thread jvagent/action/handoff_action/handoff_action.py Outdated
Comment thread jvagent/action/handoff_action/handoff_action.py Outdated
Comment thread jvagent/action/handoff_action/handoff_action.py Outdated
This commit updates the version of the jvagent package to 0.1.8rc20-dev3. Additionally, it enhances the `handoff_action` by refining the customer contact resolution logic for WhatsApp group interactions, ensuring that the current participant is prioritized over saved contacts. The `MCPClientWrapper` has been updated to support an optional pre-configured HTTP client for improved request handling. New utility functions for managing tool permissions and access control have also been introduced, enhancing the overall functionality and security of the orchestrator actions.
This commit refines the service key authentication logic in the `MCPAction` class by consolidating the formatting of the `key_env` parameter. The changes enhance code readability and maintainability without altering the functionality of the authentication process.
This commit modifies the Dockerfile to clone the `dev-tj` branch of the jvagent repository instead of the `main` branch. Additionally, the GitHub Actions workflow is updated to trigger on pushes to the `dev-tj` branch, ensuring that version bumps in `jvagent/version.py` are automatically tagged in the correct branch context.
This commit updates the Dockerfile to clone the `main` branch of the jvagent repository instead of the `dev-tj` branch. The GitHub Actions workflow is also modified to trigger on pushes to the `main` branch. Additionally, the jvagent version is bumped to `0.1.8rc19`, reflecting the latest changes and ensuring consistency across the project.
…tion

This commit refines the logging statement in the `maybe_auto_sync` function by removing unnecessary line breaks, enhancing code readability without changing the functionality of the logging process.
This commit refactors the lead generation codebase by replacing instances of the field 'name' with 'full_name' across various files, including validation, specifications, and documentation. This change ensures consistency in field naming and improves clarity in the lead capture process.

@eldonm eldonm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed current head 5230fc7 against dev, including the follow-up fixes for the six earlier findings. The affected regression suite passes, but three independent failure-injection cases still fail: OAuth credential forwarding across origins, service-key disclosure across origins, and cross-worker pending-question lost updates. I cannot clear this revision for merging. Details and remediation are inline. All HTTP requests used MockTransport; all credentials were synthetic; no external messages were sent.

Comment thread jvagent/action/mcp/integral_oauth_auth.py
Comment thread jvagent/action/mcp/service_key_auth.py Outdated
Comment thread jvagent/action/handoff_action/handoff_action.py Outdated
…odes

Reject cross-origin and HTTPS-to-HTTP MCP redirects before secrets leave the
trusted origin, and store handoff pending questions as independent
HandoffQuestion records so concurrent workers cannot clobber each other.

Co-authored-by: Cursor <cursoragent@cursor.com>
Tharickv75 and others added 3 commits October 15, 2026 10:24
Pending rows live only on HandoffQuestion nodes; keep an in-memory cache
and a one-shot migrate that clears leftover Action context keys.

Co-authored-by: Cursor <cursoragent@cursor.com>
jvspatial rejects undeclared instance attrs; PrivateAttr lets refresh
cache pending rows in memory without persisting them on the Action.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit refines the formatting of assertions in the handoff action test suite for better readability. The changes include adjusting the alignment of multi-line assertions to enhance clarity without altering the test logic.

@eldonm eldonm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Re-reviewed the four follow-up commits through a2571cb. The prior three blockers are addressed: authenticated redirect chains now reject other origins and HTTPS downgrades before sending; independently persisted HandoffQuestion nodes avoid the old shared-list lost update. I also verified concurrent independent creates against the real JSON adapter.

Two new issues in the storage refactor prevent clearance: question-by-ID operations do not enforce agent ownership, and the legacy Action-list migration cannot read old fields after an actual database cold load. Details are inline.

Validation: 871 affected tests passed, one skipped; all seven current GitHub checks are green. Additional real-JSON boundary tests reproduced both findings; independent-node round-trip and concurrent-create checks passed. Customer delivery and knowledge ingestion in the ownership reproduction were mocked; no external messages were sent. No source changes, commits, pushes, or merges were made during this re-review.

Comment thread jvagent/action/handoff_action/handoff_action.py Outdated
Comment thread jvagent/action/handoff_action/handoff_action.py Outdated
Tharickv75 and others added 2 commits October 15, 2026 16:19
Require matching agent_id before get/update/patch/remove on HandoffQuestion
ids, and drop the non-functional Action-blob migrate path after those fields
were removed.

Co-authored-by: Cursor <cursoragent@cursor.com>
Updated the documentation and code comments for the `handoff_consult_staff` response to specify that only ids fully answered by the message should be included, and to group ids only when questions share the same topic or intent. This change aims to improve clarity and ensure proper handling of pending questions in the handoff process.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants