🎉 Initialize module repository

This commit is contained in:
Marc Wempe
2026-04-03 23:08:58 +02:00
commit 09e436bbe4
12 changed files with 3122 additions and 0 deletions

View File

@@ -0,0 +1,169 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="mvd_tcg_deck_view_form_openai_inherit" model="ir.ui.view">
<field name="name">mvd.tcg.deck.view.form.openai.inherit</field>
<field name="model">mvd.tcg.deck</field>
<field name="inherit_id" ref="mvd_tcg_mtg_deck.mvd_tcg_deck_view_form_mtg_inherit"/>
<field name="arch" type="xml">
<xpath expr="//page[@name='mtg_analysis']/group[1]" position="before">
<group string="AI Deck Analysis" invisible="not is_mtg_deck">
<group groups="mvd_tcg_base.mvd_tcg_base_group_manager,base.group_system">
<field name="mtg_openai_analysis_state" readonly="1"/>
<field name="mtg_openai_last_analyzed_at" readonly="1"/>
<field
name="mtg_openai_last_error"
readonly="1"
invisible="not mtg_openai_last_error"
groups="mvd_tcg_base.mvd_tcg_base_group_manager,base.group_system"
/>
</group>
<group>
<button
name="action_mtg_openai_analyze_deck"
type="object"
string="Analyze Deck"
class="btn-primary"
groups="mvd_tcg_base.mvd_tcg_base_group_manager,base.group_system"
/>
<button
name="action_mtg_openai_suggest_alternatives"
type="object"
string="Suggest Alternatives"
class="btn-secondary"
groups="mvd_tcg_base.mvd_tcg_base_group_manager,base.group_system"
/>
<button
name="action_mtg_openai_fill_deck"
type="object"
string="Fill Deck"
class="btn-secondary"
groups="mvd_tcg_base.mvd_tcg_base_group_manager,base.group_system"
/>
</group>
<group col="1">
<field
name="mtg_openai_commander_summary"
widget="html"
readonly="1"
nolabel="1"
invisible="not mtg_openai_commander_summary"
/>
</group>
<group string="Game Plan" col="1" invisible="not mtg_openai_gameplan">
<field name="mtg_openai_gameplan" widget="html" readonly="1" nolabel="1"/>
</group>
<group string="Pilot Tips" col="1" invisible="not mtg_openai_pilot_tips">
<field name="mtg_openai_pilot_tips" widget="html" readonly="1" nolabel="1"/>
</group>
<group string="Risk Notes" col="1" invisible="not mtg_openai_risk_notes">
<field name="mtg_openai_risk_notes" widget="html" readonly="1" nolabel="1"/>
</group>
<group string="Alternative Suggestions" invisible="not is_mtg_deck">
<group groups="mvd_tcg_base.mvd_tcg_base_group_manager,base.group_system">
<field name="mtg_openai_alternative_state" readonly="1"/>
<field name="mtg_openai_alternative_last_analyzed_at" readonly="1"/>
<field
name="mtg_openai_alternative_last_error"
readonly="1"
invisible="not mtg_openai_alternative_last_error"
groups="mvd_tcg_base.mvd_tcg_base_group_manager,base.group_system"
/>
</group>
<group col="1" invisible="not mtg_openai_alternative_suggestions">
<field
name="mtg_openai_alternative_suggestions"
widget="html"
readonly="1"
nolabel="1"
/>
</group>
</group>
<group string="Deck Fill" invisible="not is_mtg_deck">
<group groups="mvd_tcg_base.mvd_tcg_base_group_manager,base.group_system">
<field name="mtg_openai_fill_state" readonly="1"/>
<field name="mtg_openai_fill_last_analyzed_at" readonly="1"/>
<field
name="mtg_openai_fill_last_error"
readonly="1"
invisible="not mtg_openai_fill_last_error"
groups="mvd_tcg_base.mvd_tcg_base_group_manager,base.group_system"
/>
</group>
<group col="1" invisible="not mtg_openai_fill_summary">
<field
name="mtg_openai_fill_summary"
widget="html"
readonly="1"
nolabel="1"
/>
</group>
</group>
<group
string="Technical"
col="1"
groups="mvd_tcg_base.mvd_tcg_base_group_administrator,base.group_system"
>
<field name="mtg_openai_last_model" readonly="1"/>
<field name="mtg_openai_last_lang" readonly="1"/>
<field name="mtg_openai_alternative_last_model" readonly="1"/>
<field name="mtg_openai_alternative_last_lang" readonly="1"/>
<field name="mtg_openai_fill_last_model" readonly="1"/>
<field name="mtg_openai_fill_last_lang" readonly="1"/>
<field name="mtg_openai_last_prompt" readonly="1" widget="text" nolabel="1"/>
<field name="mtg_openai_last_response" readonly="1" widget="text" nolabel="1"/>
<field name="mtg_openai_alternative_last_prompt" readonly="1" widget="text" nolabel="1"/>
<field name="mtg_openai_alternative_last_response" readonly="1" widget="text" nolabel="1"/>
<field name="mtg_openai_fill_last_prompt" readonly="1" widget="text" nolabel="1"/>
<field name="mtg_openai_fill_last_response" readonly="1" widget="text" nolabel="1"/>
</group>
</group>
<group
string="AI Card Roles"
invisible="not is_mtg_deck"
groups="mvd_tcg_base.mvd_tcg_base_group_manager,base.group_system"
>
<group>
<field name="mtg_openai_role_analysis_state" readonly="1"/>
<field name="mtg_openai_role_last_analyzed_at" readonly="1"/>
<field
name="mtg_openai_role_last_error"
readonly="1"
invisible="not mtg_openai_role_last_error"
groups="mvd_tcg_base.mvd_tcg_base_group_manager,base.group_system"
/>
</group>
<group>
<button
name="action_mtg_openai_analyze_card_roles"
type="object"
string="Analyze Card Roles"
class="btn-secondary"
groups="mvd_tcg_base.mvd_tcg_base_group_manager,base.group_system"
/>
</group>
<group col="1">
<field name="line_ids" readonly="1" nolabel="1">
<list create="0" delete="0" default_order="board_sequence, sequence, id">
<field name="board_id" optional="show"/>
<field name="card_id"/>
<field name="role_ids" widget="many2many_tags" options="{'color_field': 'color'}" optional="show"/>
<field name="mtg_openai_role_rationale" optional="show"/>
</list>
</field>
</group>
<group
string="Technical"
col="1"
groups="mvd_tcg_base.mvd_tcg_base_group_administrator,base.group_system"
>
<field name="mtg_openai_role_last_model" readonly="1"/>
<field name="mtg_openai_role_last_lang" readonly="1"/>
<field name="mtg_openai_role_last_prompt" readonly="1" widget="text" nolabel="1"/>
<field name="mtg_openai_role_last_response" readonly="1" widget="text" nolabel="1"/>
</group>
</group>
</xpath>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form_mvd_tcg_mtg_deck_openai" model="ir.ui.view">
<field name="name">res.config.settings.view.form.mvd.tcg.mtg.deck.openai</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="mvd_tcg_base.mvd_tcg_res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//app[@name='mvd_tcg']" position="inside">
<block
title="OpenAI Analysis"
name="mvd_tcg_openai_analysis"
groups="mvd_tcg_base.mvd_tcg_base_group_administrator,base.group_system"
>
<setting
id="mvd_tcg_openai_model_name"
string="Model Name"
help="Default model used for deck summaries, role tagging, deck fill, and alternative suggestions."
>
<field name="mtg_openai_model_name" placeholder="gpt-5-mini"/>
</setting>
<setting
id="mvd_tcg_openai_api_base_url"
string="API Base URL"
help="Override the OpenAI API base URL only for special environments or proxies."
>
<field name="mtg_openai_api_base_url"/>
</setting>
<setting
id="mvd_tcg_openai_request_timeout"
string="Request Timeout"
help="Timeout in seconds for OpenAI responses requests."
>
<field name="mtg_openai_request_timeout_seconds"/>
</setting>
<setting
id="mvd_tcg_openai_role_batch_size"
string="Role Analysis Batch Size"
help="How many deck lines are sent in one role-analysis request."
>
<field name="mtg_openai_role_batch_size"/>
</setting>
<setting
id="mvd_tcg_openai_fill_candidate_limit"
string="Deck Fill Candidate Limit"
help="Maximum number of in-system candidate cards considered for AI-assisted deck fill."
>
<field name="mtg_openai_fill_candidate_limit"/>
</setting>
<setting
id="mvd_tcg_openai_fill_batch_size"
string="Deck Fill Batch Size"
help="Maximum number of cards the AI may add in one fill iteration."
>
<field name="mtg_openai_fill_batch_size"/>
</setting>
<setting
id="mvd_tcg_openai_alternative_candidate_limit"
string="Alternative Candidate Limit"
help="Maximum number of in-system replacement candidates passed for one problematic deck line."
>
<field name="mtg_openai_alternative_candidate_limit"/>
</setting>
<setting
id="mvd_tcg_openai_api_key"
string="API Key"
help="Stored in system parameters and used for OpenAI-backed MTG deck analysis."
>
<field name="mtg_openai_api_key" password="True" placeholder="sk-..."/>
</setting>
</block>
</xpath>
</field>
</record>
</odoo>