Skip to content

Split support workflow into specialist agents - #1

Open
sri-rang wants to merge 4 commits into
mainfrom
feature/support-subagents
Open

Split support workflow into specialist agents#1
sri-rang wants to merge 4 commits into
mainfrom
feature/support-subagents

Conversation

@sri-rang

@sri-rang sri-rang commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add a customer-facing supervisor with purchase and refund specialist sub-agents
  • Restrict each specialist to its required tools and approval policy
  • Organize specialist prompts, configuration, and shared tools in a dedicated deeplyagentic.subagents package
  • Enforce customer ownership for invoice details and refund requests
  • Use unique conversation thread IDs and update setup documentation

Structure

  • deeplyagentic/main.py — supervisor, identity verification, interrupts, and CLI
  • deeplyagentic/subagents/purchase_specialist.py — read-only purchase specialist
  • deeplyagentic/subagents/refund_specialist.py — approval-gated refund specialist
  • deeplyagentic/subagents/tools.py — shared API-backed specialist tools
  • deeplyagentic/api.py — shared RiffDesk API client configuration

Test plan

  • Compile all Python modules
  • Verify owned invoice access succeeds
  • Verify cross-customer invoice access returns 404
  • Verify cross-customer refund requests return 404
  • Import and construct the supervisor successfully
  • Verify each specialist exports the expected restricted toolset
  • Pass git diff --check

@qodo-code-review

qodo-code-review Bot commented Jul 11, 2026

Copy link
Copy Markdown

PR Summary by Qodo

Split RiffDesk support bot into supervisor + purchase/refund specialist subagents

✨ Enhancement 🐞 Bug fix 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Introduce a customer-facing supervisor that delegates to purchase and refund specialists.
• Restrict specialist tool access and gate refund actions behind explicit human approval.
• Enforce customer ownership checks for invoice detail and refund requests via API scoping.
Diagram

graph TD
  C([Customer]) --> S["deeplyagentic/main.py (Supervisor)"] --> ID["collect_customer_identity"] --> API["riffdesk/main.py (REST API)"] --> DB[("SQLite DB")]
  S --> PS["purchase-specialist"] --> Tread["subagents/tools.py (read tools)"] --> API
  S --> RS["refund-specialist"] --> Twrite["subagents/tools.py (refund tool)"] --> API
  subgraph Legend
    direction LR
    _user(["User/Caller"]) ~~~ _mod["Module/Agent"] ~~~ _db[("Database")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Server-derived customer identity (no customer_id parameter)
  • ➕ Stronger security model: customer scope cannot be forged by the client/agent
  • ➕ Simplifies tool signatures and reduces chance of accidental ID substitution
  • ➖ Requires an auth/session mechanism (JWT, per-customer API keys, or login) beyond the current demo setup
  • ➖ More invasive changes across the API and agent initialization
2. Single agent with tool-level policies (no subagents)
  • ➕ Fewer moving parts (no delegation boundaries) and simpler prompting surface
  • ➕ Easier to debug a single decision-making loop
  • ➖ Harder to enforce least-privilege tool access (refund vs read-only)
  • ➖ Approval gating and separation-of-duties becomes prompt-dependent rather than structurally enforced

Recommendation: The PR’s supervisor + specialist split is a good fit for least-privilege and approval-gated actions while keeping the demo architecture lightweight. If this evolves beyond a demo, consider moving from explicit customer_id parameters to server-derived identity (auth/session) to eliminate any possibility of ID spoofing at the API boundary.

Files changed (9) +172 / -76

Enhancement (4) +63 / -68
__init__.pyAdd package docstring for deeplyagentic +1/-0

Add package docstring for deeplyagentic

• Introduces a minimal package-level docstring to describe the agent-based support application.

deeplyagentic/init.py

main.pyConvert single-agent workflow into supervisor delegating to subagents +18/-68

Convert single-agent workflow into supervisor delegating to subagents

• Removes inline invoice/refund tools from the supervisor and wires in purchase/refund subagents with scoped toolsets. Uses the shared API client, strengthens supervisor prompt to require delegation, and randomizes the conversation thread_id per run.

deeplyagentic/main.py

purchase_specialist.pyAdd read-only purchase specialist definition +19/-0

Add read-only purchase specialist definition

• Introduces the purchase specialist configuration with a read-only mandate. Restricts tools to invoice listing and invoice detail lookups.

deeplyagentic/subagents/purchase_specialist.py

refund_specialist.pyAdd approval-gated refund specialist definition +25/-0

Add approval-gated refund specialist definition

• Introduces the refund specialist configuration requiring invoice ownership verification before refund requests. Configures 'request_refund' to be interrupt/approval-gated with approve/reject decisions.

deeplyagentic/subagents/refund_specialist.py

Bug fix (2) +66 / -6
tools.pyCentralize specialist tools and enforce customer-scoped invoice access +52/-0

Centralize specialist tools and enforce customer-scoped invoice access

• Adds shared LangChain tools for invoice listing, invoice detail, and refund requests using the shared API client. Updates tool signatures to include customer_id and treats 404 as 'not owned' for invoice detail and refund attempts.

deeplyagentic/subagents/tools.py

main.pyEnforce customer ownership on invoice detail and refund creation endpoints +14/-6

Enforce customer ownership on invoice detail and refund creation endpoints

• Extends the refund request schema to include customer_id. Updates invoice detail and refund creation queries to filter by (invoice_id, customer_id) and return 404 when the invoice is not owned by the customer.

riffdesk/main.py

Refactor (2) +23 / -0
api.pyExtract shared httpx client configuration for RiffDesk API +17/-0

Extract shared httpx client configuration for RiffDesk API

• Adds a single place to configure base URL and API key via environment variables. Provides an 'api_client()' helper used by supervisor and specialist tools.

deeplyagentic/api.py

__init__.pyCreate subagents package exports for specialists +6/-0

Create subagents package exports for specialists

• Adds a dedicated package for specialist agents and exposes 'purchase_specialist' and 'refund_specialist' via '__all__'.

deeplyagentic/subagents/init.py

Documentation (1) +20 / -2
README.mdDocument supervisor/specialist workflow and new run instructions +20/-2

Document supervisor/specialist workflow and new run instructions

• Replaces the minimal run snippet with an overview of the support supervisor and two specialists. Updates the invocation to run 'python -m deeplyagentic.main' and documents API URL/key environment overrides.

README.md

@qodo-code-review

qodo-code-review Bot commented Jul 11, 2026

Copy link
Copy Markdown

Code Review by Qodo

Context used
✅ Compliance rules (platform): 10 rules

Action required

1. get_invoice() missing docstring ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The modified FastAPI handler get_invoice() has no docstring as the first statement in the function
body. This violates the requirement that all new or modified Python functions include an immediate
docstring for maintainability and auditability.
Code

riffdesk/main.py[R179-184]

+def get_invoice(
+    invoice_id: int,
+    customer_id: int = Query(...),
+    db: sqlite3.Connection = Depends(get_db),
+) -> InvoiceDetail:
    invoice = db.execute(
-        "SELECT InvoiceId, InvoiceDate, Total FROM Invoice WHERE InvoiceId = ?",
-        (invoice_id,),
Evidence
PR Compliance ID 784431 requires every new or modified Python function definition to have an
immediate docstring as the first statement. In riffdesk/main.py, the modified get_invoice()
definition is followed directly by invoice = db.execute(...) with no docstring present.

Rule 784431: Require docstrings for all Python functions
riffdesk/main.py[179-184]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The modified Python function `get_invoice()` lacks a docstring as the first statement in its body, which violates the docstring requirement for all new/modified functions.

## Issue Context
`get_invoice()` is a FastAPI route handler whose signature was changed in this PR (added required `customer_id` query param). The function body begins immediately with a database query instead of a docstring.

## Fix Focus Areas
- riffdesk/main.py[179-190]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Comment thread riffdesk/main.py
@qodo-code-review

Copy link
Copy Markdown

Qodo Fixer

🍒 Ready to be cherry-picked — ✅ Merged (0) · ☑ Fixed (1)

Grey Divider

🔗 Fix PR: #2

This fix PR was closed automatically. Its branch is preserved so you can cherry pick the changes into the original PR.

Prompt for coding agent

This is an automated fix prepared on a separate branch (#2). It is NOT applied to this PR.
To use it: review Fix PR #2 (https://github.com/Shape-Machine/openchain/pull/2), evaluate each change critically against your local context, and cherry-pick the changes that are correct into this branch. Do not accept them blindly.
Process — 1 fixed
  • ☑ Fixed: get_invoice() missing docstring

@sri-rang

Copy link
Copy Markdown
Contributor Author

/agentic_describe

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.

1 participant