The old flow fired OpenAI on wizard open with just ticket + chatter,
so the AI summary was just a paraphrase of what the user originally
reported — your engineering analysis (scope, limitations, recommended
approach) never made it to the owner. Restructure to a two-step flow:
1. Open wizard → empty findings + empty summary, NO OpenAI call
2. You write findings: scope / effort / approach / risk
3. Click 'Generate Summary from Findings' → OpenAI runs with
ticket + chatter + findings, where the prompt explicitly tells
the model to weight findings MORE THAN the original report
4. Review/edit, then Send
Bulk wizard mirrors the flow per line: each row gets its own
findings + summary, one 'Generate All Summaries' button fans out
parallel OpenAI calls using each line's own findings.
Updated SUMMARY_PROMPT to:
- Tell the model the support engineer's findings are authoritative
- Emit a bullet structure that leads with the recommendation, not
the user's restated ask
- Side with findings over the original report when they conflict
New tests cover:
- default_get does NOT fire OpenAI (regression guard for auto-AI)
- Findings text actually reaches the OpenAI prompt
- Send works with a manually-typed summary (no AI in the loop)
- Existing bulk + validation paths still pass with the new shape
Also folds in the deferred code-review #7: ThreadPoolExecutor now
explicitly cancels pending futures on timeout via
shutdown(wait=False, cancel_futures=True) so a slow OpenAI day can't
hold the wizard open for ceil(N/workers)*15s.
Bumps fusion_helpdesk_central to 19.0.2.3.0.
Smoke-tested live on nexa: opening the wizard makes zero OpenAI calls;
clicking Generate with findings='My findings: scope is XL, ~8h' makes
exactly one call and the findings text is verifiably in the prompt
body received by call_openai_chat.
105 lines
5.1 KiB
XML
105 lines
5.1 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!--
|
|
Copyright 2026 Nexa Systems Inc.
|
|
License OPL-1
|
|
|
|
The owner-approval engagement wizard, opened from the ticket form
|
|
button OR the list-view bulk server action. Branches on `mode` to
|
|
show either the single-ticket layout (one AI summary field) or the
|
|
bulk layout (an editable line per ticket).
|
|
-->
|
|
<odoo>
|
|
|
|
<record id="view_engagement_wizard_form" model="ir.ui.view">
|
|
<field name="name">fusion.helpdesk.engagement.wizard.form</field>
|
|
<field name="model">fusion.helpdesk.engagement.wizard</field>
|
|
<field name="arch" type="xml">
|
|
<form string="Request Owner Approval">
|
|
<field name="mode" invisible="1"/>
|
|
<field name="ticket_id" invisible="1"/>
|
|
|
|
<group>
|
|
<group>
|
|
<field name="owner_name_display" string="Owner"/>
|
|
<field name="owner_email_display" string="Owner Email" widget="email"/>
|
|
</group>
|
|
</group>
|
|
|
|
<div class="alert alert-warning" role="alert"
|
|
invisible="not ai_unavailable">
|
|
<strong>AI summary unavailable.</strong>
|
|
OpenAI didn't return a summary (no API key set, rate limit,
|
|
or network error). Write a quick brief in the Summary
|
|
field below before sending — everything else still works.
|
|
</div>
|
|
|
|
<!--
|
|
Single mode. The user fills findings first, clicks
|
|
Generate Summary, reviews the AI output, edits if needed,
|
|
then Sends. We deliberately don't auto-fire OpenAI on
|
|
open — the AI needs the engineer's analysis to be useful.
|
|
-->
|
|
<group invisible="mode != 'single'">
|
|
<field name="personal_note"
|
|
placeholder="One-line note that appears above the summary in the email…"/>
|
|
</group>
|
|
<group invisible="mode != 'single'" string="1. Your Findings">
|
|
<field name="findings" nolabel="1"
|
|
placeholder="What did your investigation surface? Scope, limitations, recommended approach, effort, risks — anything the owner needs to know that the original reporter wouldn't have."/>
|
|
</group>
|
|
<group invisible="mode != 'single'" string="2. Summary to Send">
|
|
<div class="o_row" colspan="2">
|
|
<button name="action_generate_summary" type="object"
|
|
string="Generate Summary from Findings"
|
|
icon="fa-magic"
|
|
class="btn-secondary"/>
|
|
<span class="o_form_label text-muted ms-2">
|
|
← click after writing your findings, then review & edit below
|
|
</span>
|
|
</div>
|
|
<field name="ai_summary" nolabel="1"
|
|
placeholder="Click Generate Summary above, or write the brief yourself. The owner reads this first."/>
|
|
</group>
|
|
|
|
<!--
|
|
Bulk mode: same two-step flow per ticket. Findings +
|
|
Summary editable inline; a single Generate All button
|
|
fans out OpenAI in parallel using each line's findings.
|
|
-->
|
|
<group invisible="mode != 'bulk'">
|
|
<field name="personal_note"
|
|
placeholder="One-line note that appears once at the top of the combined email…"/>
|
|
</group>
|
|
<div class="o_row" colspan="2"
|
|
invisible="mode != 'bulk'">
|
|
<button name="action_generate_all_summaries" type="object"
|
|
string="Generate All Summaries"
|
|
icon="fa-magic"
|
|
class="btn-secondary"/>
|
|
<span class="o_form_label text-muted ms-2">
|
|
← fill in findings per row first, then click to regenerate all summaries in parallel
|
|
</span>
|
|
</div>
|
|
<field name="line_ids" invisible="mode != 'bulk'" nolabel="1">
|
|
<list editable="bottom" create="0" delete="0">
|
|
<field name="ticket_id" readonly="1"/>
|
|
<field name="ticket_name" readonly="1"/>
|
|
<field name="findings"
|
|
placeholder="Your engineering findings for this ticket…"/>
|
|
<field name="ai_summary"
|
|
placeholder="(empty — click Generate All above, or write by hand)"/>
|
|
</list>
|
|
</field>
|
|
|
|
<footer>
|
|
<button name="action_send" type="object"
|
|
string="Send Engagement"
|
|
class="btn-primary"/>
|
|
<button special="cancel" string="Cancel"/>
|
|
</footer>
|
|
</form>
|
|
</field>
|
|
</record>
|
|
|
|
</odoo>
|