This commit is contained in:
gsinghpal
2026-04-03 15:45:18 -04:00
parent 4cd7357aa0
commit c66bdf5089
71 changed files with 6721 additions and 118 deletions

View File

@@ -31,12 +31,56 @@ RESPONSE FORMATTING:
- Use rich Markdown formatting in your responses. The chat renders Markdown as HTML.
- Use **bold** for account names, amounts, and key terms.
- Use ## and ### headers to organize sections in longer responses.
- Use Markdown tables for tabular data (| col1 | col2 | format).
- Use bullet lists (- item) for findings, issues, and action items.
- Use numbered lists (1. item) for sequential steps or ranked items.
- Use `code` for account codes, reference numbers, and technical IDs.
- Use --- horizontal rules to separate sections in long reports.
INTERACTIVE TABLES (fusion-table) — MANDATORY FOR ACTIONABLE DATA:
IMPORTANT: When a tool returns a list of records that the user could act on, you MUST use
a ```fusion-table block instead of a Markdown table. This is REQUIRED — never use plain
Markdown tables for actionable data. The fusion-table renders an interactive widget with
checkboxes, your AI recommendations per row, user input fields, and bulk action buttons.
YOU MUST USE fusion-table FOR: missing ITCs/tax (find_missing_itc_bills, find_missing_tax_invoices),
duplicate entries (find_duplicate_bills, find_duplicate_entries), overdue invoices (get_overdue_invoices),
unreconciled lines (get_unreconciled_bank_lines, get_unreconciled_receipts, get_unmatched_payments,
find_unreconciled_suspense), draft entries (find_draft_entries), wrong balances
(find_wrong_direction_balances), sequence gaps (find_sequence_gaps), wrong accounts
(find_wrong_account_entries), unpaid bills (get_unpaid_bills), and any other list where
the user needs to review, dismiss, flag, or create rules for individual rows.
USE REGULAR MARKDOWN TABLES ONLY FOR: P&L (get_profit_loss), balance sheet (get_balance_sheet),
trial balance (get_trial_balance), cash flow (get_cash_flow), period summaries, tax reports,
and any purely informational/read-only data where there is nothing to act on per row.
Format: wrap a JSON object in a ```fusion-table fenced code block:
```fusion-table
{
"mode": "interactive",
"title": "Descriptive Title",
"columns": ["Col1", "Col2", "Col3"],
"rows": [
{"id": 123, "cells": ["val1", "val2", "val3"], "recommendation": {"action": "dismiss", "reason": "Brief explanation"}},
{"id": 456, "cells": ["val1", "val2", "val3"], "recommendation": {"action": "flag", "reason": "Brief explanation"}}
],
"actions": ["dismiss", "flag", "create_rule"],
"source_tool": "tool_name_that_produced_this"
}
```
- "mode": "interactive" (actionable) or "readonly" (informational but structured)
- "id": the Odoo record ID (account.move id, account.bank.statement.line id, etc.)
- "recommendation.action": one of "dismiss", "flag", "create_rule"
- "recommendation.reason": short explanation of why you recommend this action
- "actions": which bulk action buttons to show
- "source_tool": the tool name that produced the data
- You MUST provide a recommendation for each row when using interactive mode.
- Format monetary amounts as "$X,XXX.XX" in cells.
- Always include the record ID so actions can target the correct Odoo record.
- Add a brief text summary before or after the fusion-table block for context.
LINKING TO ODOO RECORDS:
- When referencing specific records, include clickable Odoo links.
- Journal entries: [INV/2026/00123](/odoo/accounting/123) where 123 is the move ID.
@@ -60,12 +104,14 @@ def _build_rules_section(rules):
for rule in rules:
priority = 'ADMIN' if rule.created_by == 'admin' else 'AI'
tier = 'auto' if rule.approval_tier == 'auto' else 'needs-approval'
conf_str = f', confidence={rule.confidence_score:.0%}, uses={rule.total_uses}' if rule.total_uses > 0 else ''
lines.append(
f'- [{priority}/{tier}] {rule.name} ({rule.rule_type}): '
f'- [{priority}/{tier}{conf_str}] {rule.name} ({rule.rule_type}): '
f'{rule.description or rule.match_logic or "No description"}'
)
if rule.match_logic:
lines.append(f' Match logic: {rule.match_logic}')
logic_text = rule.match_logic[:500] # Prevent prompt bloat
lines.append(f' Match logic: {logic_text}')
return '\n'.join(lines)
@@ -73,7 +119,9 @@ def _build_history_section(history):
if not history:
return ''
lines = ['RECENT MATCH HISTORY (learn from these patterns):']
for h in history[:50]:
# A4: Don't hard-cap at 50 — the caller (_load_match_history) already
# respects the history_in_prompt config setting
for h in history:
status = h.decision
reason = ''
if h.rejection_reason: