[WIP] Add human in the loop (HITL) BBE examples - #6414
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdded two Ballerina banking agent examples. One uses explicit human approval for transfers. The other requires approval only for transfers above 500. Both include interactive session resumption, documentation, metadata, catalog entries, and the AI library version update. ChangesAI agent approval examples
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant main
participant bankingAgent
participant AccountStore
User->>main: Submit banking request
main->>bankingAgent: Run request
bankingAgent-->>main: ApprovalRequiredError
main->>User: Collect approval decision
main->>bankingAgent: Resume session
bankingAgent->>AccountStore: Validate and update balances
Possibly related issues
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 `@examples/ai-agent-conditional-approval/ai_agent_conditional_approval.bal`:
- Around line 40-53: Update transfer to reject non-positive amounts and
identical fromAccount/toAccount values before checking balances or modifying
accounts. Preserve the existing not-found and insufficient-funds validation, and
return descriptive errors for both new invalid-input cases.
In `@examples/ai-agent-human-in-the-loop/ai_agent_human_in_the_loop.bal`:
- Around line 31-44: Update transfer to reject amounts that are not greater than
0d and transfers where fromAccount and toAccount refer to the same account,
before modifying accounts. Preserve the existing account lookup and
insufficient-funds checks, and only execute the debit and credit assignments
after both validations pass.
🪄 Autofix
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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: c17774f1-3b45-4b26-9234-1f4aa98c8b61
⛔ Files ignored due to path filters (2)
examples/ai-agent-conditional-approval/ai_agent_conditional_approval.outis excluded by!**/*.outexamples/ai-agent-human-in-the-loop/ai_agent_human_in_the_loop.outis excluded by!**/*.out
📒 Files selected for processing (7)
examples/ai-agent-conditional-approval/ai_agent_conditional_approval.balexamples/ai-agent-conditional-approval/ai_agent_conditional_approval.mdexamples/ai-agent-conditional-approval/ai_agent_conditional_approval.metatagsexamples/ai-agent-human-in-the-loop/ai_agent_human_in_the_loop.balexamples/ai-agent-human-in-the-loop/ai_agent_human_in_the_loop.mdexamples/ai-agent-human-in-the-loop/ai_agent_human_in_the_loop.metatagsexamples/index.json
| isolated function transfer(string fromAccount, string toAccount, decimal amount) | ||
| returns string|error { | ||
| lock { | ||
| Account? sender = accounts[fromAccount]; | ||
| Account? recipient = accounts[toAccount]; | ||
| if sender is () || recipient is () { | ||
| return error("One or both accounts were not found."); | ||
| } | ||
| if sender.balance < amount { | ||
| return error(string `Insufficient funds in account '${fromAccount}'.`); | ||
| } | ||
| // Debit the sender and credit the recipient. | ||
| accounts[fromAccount] = {id: sender.id, owner: sender.owner, balance: sender.balance - amount}; | ||
| accounts[toAccount] = {id: recipient.id, owner: recipient.owner, balance: recipient.balance + amount}; |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🔴 Critical | ⚡ Quick win
Validate transfer invariants before balance updates.
Reject amount <= 0d. A negative amount reverses the transfer direction.
Reject identical fromAccount and toAccount. The second assignment then overwrites the debit and increases the account balance by amount.
Proposed fix
isolated function transfer(string fromAccount, string toAccount, decimal amount)
returns string|error {
+ if amount <= 0d {
+ return error("Transfer amount must be greater than zero.");
+ }
+ if fromAccount == toAccount {
+ return error("Source and destination accounts must be different.");
+ }
lock {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| isolated function transfer(string fromAccount, string toAccount, decimal amount) | |
| returns string|error { | |
| lock { | |
| Account? sender = accounts[fromAccount]; | |
| Account? recipient = accounts[toAccount]; | |
| if sender is () || recipient is () { | |
| return error("One or both accounts were not found."); | |
| } | |
| if sender.balance < amount { | |
| return error(string `Insufficient funds in account '${fromAccount}'.`); | |
| } | |
| // Debit the sender and credit the recipient. | |
| accounts[fromAccount] = {id: sender.id, owner: sender.owner, balance: sender.balance - amount}; | |
| accounts[toAccount] = {id: recipient.id, owner: recipient.owner, balance: recipient.balance + amount}; | |
| isolated function transfer(string fromAccount, string toAccount, decimal amount) | |
| returns string|error { | |
| if amount <= 0d { | |
| return error("Transfer amount must be greater than zero."); | |
| } | |
| if fromAccount == toAccount { | |
| return error("Source and destination accounts must be different."); | |
| } | |
| lock { | |
| Account? sender = accounts[fromAccount]; | |
| Account? recipient = accounts[toAccount]; | |
| if sender is () || recipient is () { | |
| return error("One or both accounts were not found."); | |
| } | |
| if sender.balance < amount { | |
| return error(string `Insufficient funds in account '${fromAccount}'.`); | |
| } | |
| // Debit the sender and credit the recipient. | |
| accounts[fromAccount] = {id: sender.id, owner: sender.owner, balance: sender.balance - amount}; | |
| accounts[toAccount] = {id: recipient.id, owner: recipient.owner, balance: recipient.balance + amount}; |
🤖 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 `@examples/ai-agent-conditional-approval/ai_agent_conditional_approval.bal`
around lines 40 - 53, Update transfer to reject non-positive amounts and
identical fromAccount/toAccount values before checking balances or modifying
accounts. Preserve the existing not-found and insufficient-funds validation, and
return descriptive errors for both new invalid-input cases.
| isolated function transfer(string fromAccount, string toAccount, decimal amount) | ||
| returns string|error { | ||
| lock { | ||
| Account? sender = accounts[fromAccount]; | ||
| Account? recipient = accounts[toAccount]; | ||
| if sender is () || recipient is () { | ||
| return error("One or both accounts were not found."); | ||
| } | ||
| if sender.balance < amount { | ||
| return error(string `Insufficient funds in account '${fromAccount}'.`); | ||
| } | ||
| // Debit the sender and credit the recipient. | ||
| accounts[fromAccount] = {id: sender.id, owner: sender.owner, balance: sender.balance - amount}; | ||
| accounts[toAccount] = {id: recipient.id, owner: recipient.owner, balance: recipient.balance + amount}; |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Reject non-positive amounts and same-account transfers.
amount has no lower-bound validation. A negative amount credits the sender and debits the recipient.
If fromAccount == toAccount, Line 44 overwrites the debit from Line 43 with balance + amount. This creates funds in the account.
Validate amount > 0d and require distinct account IDs before updating accounts.
Proposed fix
isolated function transfer(string fromAccount, string toAccount, decimal amount)
returns string|error {
+ if amount <= 0d {
+ return error("Transfer amount must be greater than zero.");
+ }
+ if fromAccount == toAccount {
+ return error("Source and destination accounts must be different.");
+ }
lock {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| isolated function transfer(string fromAccount, string toAccount, decimal amount) | |
| returns string|error { | |
| lock { | |
| Account? sender = accounts[fromAccount]; | |
| Account? recipient = accounts[toAccount]; | |
| if sender is () || recipient is () { | |
| return error("One or both accounts were not found."); | |
| } | |
| if sender.balance < amount { | |
| return error(string `Insufficient funds in account '${fromAccount}'.`); | |
| } | |
| // Debit the sender and credit the recipient. | |
| accounts[fromAccount] = {id: sender.id, owner: sender.owner, balance: sender.balance - amount}; | |
| accounts[toAccount] = {id: recipient.id, owner: recipient.owner, balance: recipient.balance + amount}; | |
| isolated function transfer(string fromAccount, string toAccount, decimal amount) | |
| returns string|error { | |
| if amount <= 0d { | |
| return error("Transfer amount must be greater than zero."); | |
| } | |
| if fromAccount == toAccount { | |
| return error("Source and destination accounts must be different."); | |
| } | |
| lock { | |
| Account? sender = accounts[fromAccount]; | |
| Account? recipient = accounts[toAccount]; | |
| if sender is () || recipient is () { | |
| return error("One or both accounts were not found."); | |
| } | |
| if sender.balance < amount { | |
| return error(string `Insufficient funds in account '${fromAccount}'.`); | |
| } | |
| // Debit the sender and credit the recipient. | |
| accounts[fromAccount] = {id: sender.id, owner: sender.owner, balance: sender.balance - amount}; | |
| accounts[toAccount] = {id: recipient.id, owner: recipient.owner, balance: recipient.balance + amount}; |
🤖 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 `@examples/ai-agent-human-in-the-loop/ai_agent_human_in_the_loop.bal` around
lines 31 - 44, Update transfer to reject amounts that are not greater than 0d
and transfers where fromAccount and toAccount refer to the same account, before
modifying accounts. Preserve the existing account lookup and insufficient-funds
checks, and only execute the debit and credit assignments after both validations
pass.
|



Purpose
$subject.
Fixes ballerina-platform/ballerina-library#9007
Summary
ai:Agenthuman-in-the-loop workflows.ailibrary dependency to version1.13.0.