This commit is contained in:
gsinghpal
2026-04-04 15:37:16 -04:00
parent c66bdf5089
commit 3cc93b8783
36 changed files with 3278 additions and 548 deletions

View File

@@ -40,9 +40,9 @@ class FusionAccountingChatController(http.Controller):
return {'status': 'closed'}
@http.route('/fusion_accounting/chat', type='jsonrpc', auth='user')
def chat(self, session_id, message, context=None, **kwargs):
if not message:
return {'error': 'Message is required'}
def chat(self, session_id, message, context=None, image=None, **kwargs):
if not message and not image:
return {'error': 'Message or image is required'}
# S3: Ownership check
session = request.env['fusion.accounting.session'].browse(int(session_id))
if session.exists():
@@ -50,7 +50,7 @@ class FusionAccountingChatController(http.Controller):
if error:
return error
agent = request.env['fusion.accounting.agent']
result = agent.chat(int(session_id), message, context=context)
result = agent.chat(int(session_id), message or '', context=context, image=image)
return result
@http.route('/fusion_accounting/approve', type='jsonrpc', auth='user')
@@ -134,6 +134,30 @@ class FusionAccountingChatController(http.Controller):
results.append({'id': mid, 'status': 'error', 'error': 'Action could not be rejected. Check server logs for details.'})
return {'results': results}
@http.route('/fusion_accounting/chat/status', type='jsonrpc', auth='user')
def chat_status(self, session_id, **kwargs):
"""Poll the live execution state of a running chat — returns thinking text,
tool calls in progress, and current status. Called every 500ms by the frontend
while a chat request is in flight."""
from ..services.agent import get_execution_state
state = get_execution_state(int(session_id))
return state
@http.route('/fusion_accounting/search_matches', type='jsonrpc', auth='user')
def search_matches(self, statement_line_id, query='', **kwargs):
"""Live search for matching journal items — called directly by the
reconciliation table search bar (no AI round-trip)."""
from ..services.tools.bank_reconciliation import search_matching_entries
try:
result = search_matching_entries(request.env, {
'statement_line_id': int(statement_line_id),
'query': query,
})
return result
except Exception as e:
_logger.exception("Search matches failed")
return {'candidates': [], 'error': str(e)}
@http.route('/fusion_accounting/session/list', type='jsonrpc', auth='user')
def session_list(self, limit=20, **kwargs):
"""List recent sessions for the session picker dropdown."""
@@ -187,10 +211,20 @@ class FusionAccountingChatController(http.Controller):
for block in msg['content']:
if isinstance(block, dict) and block.get('type') == 'text' and block['text'].strip():
display_messages.append({'role': msg['role'], 'content': block['text']})
# Include any pending approvals so they show on page load
agent = request.env['fusion.accounting.agent']
pending = request.env['fusion.accounting.match.history'].search([
('session_id', '=', session.id),
('decision', '=', 'pending'),
])
pending_approvals = [agent._format_pending_approval(p) for p in pending]
return {
'session_id': session.id,
'messages': display_messages,
'name': session.name,
'pending_approvals': pending_approvals,
}
@http.route('/fusion_accounting/session/history', type='jsonrpc', auth='user')