🎉 Initialize module repository
This commit is contained in:
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
.DS_Store
|
||||||
|
.pytest_cache/
|
||||||
|
.ruff_cache/
|
||||||
|
*.log
|
||||||
|
*.swp
|
||||||
|
*~
|
||||||
1
__init__.py
Normal file
1
__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import models
|
||||||
30
__manifest__.py
Normal file
30
__manifest__.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "MVD TCG MTG Deck OpenAI",
|
||||||
|
"summary": "OpenAI-powered deck and card-role analysis for MTG decks",
|
||||||
|
"version": "19.0.6.4.1",
|
||||||
|
"description": """
|
||||||
|
OpenAI-powered analysis layer for the MTG deckbuilder.
|
||||||
|
|
||||||
|
This module adds on-demand AI support to Magic decks:
|
||||||
|
- commander-focused deck summaries
|
||||||
|
- game-plan, pilot-tip, and risk-note analysis
|
||||||
|
- role-tag suggestion and rationale for deck lines
|
||||||
|
- alternative-card suggestions for problematic deck lines
|
||||||
|
- AI-assisted deck fill from the in-system card pool
|
||||||
|
- report integration for the generated deck analysis
|
||||||
|
|
||||||
|
The analysis follows the active user language while keeping English oracle
|
||||||
|
text as the authoritative rules input.
|
||||||
|
""",
|
||||||
|
"category": "Tools",
|
||||||
|
"author": "Mantjeverse Digital",
|
||||||
|
"license": "LGPL-3",
|
||||||
|
"depends": ["mvd_tcg_base", "mvd_tcg_deck", "mvd_tcg_mtg_deck"],
|
||||||
|
"data": [
|
||||||
|
"views/res_config_settings_views.xml",
|
||||||
|
"views/mvd_tcg_mtg_deck_views.xml",
|
||||||
|
"report/mvd_tcg_mtg_deck_report_templates.xml",
|
||||||
|
],
|
||||||
|
"application": False,
|
||||||
|
"installable": True,
|
||||||
|
}
|
||||||
592
i18n/de.po
Normal file
592
i18n/de.po
Normal file
@@ -0,0 +1,592 @@
|
|||||||
|
# Translation of Odoo Server.
|
||||||
|
# This file contains the translation of the following modules:
|
||||||
|
# * mvd_tcg_mtg_deck_openai
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: Odoo Server 19.0+e-20260324\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2026-04-03 05:05+0000\n"
|
||||||
|
"PO-Revision-Date: 2026-04-03 05:05+0000\n"
|
||||||
|
"Last-Translator: \n"
|
||||||
|
"Language-Team: \n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Language: de\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.mvd_tcg_deck_view_form_openai_inherit
|
||||||
|
msgid "AI Card Roles"
|
||||||
|
msgstr "KI-Kartenrollen"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.mvd_tcg_deck_view_form_openai_inherit
|
||||||
|
msgid "AI Deck Analysis"
|
||||||
|
msgstr "KI-Deckanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid "OpenAI API Base URL"
|
||||||
|
msgstr "OpenAI-API-Basis-URL"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_res_config_settings__mtg_openai_api_key
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid "API Key"
|
||||||
|
msgstr "API-Schlüssel"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_res_config_settings__mtg_openai_alternative_candidate_limit
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid "Alternative Candidate Limit"
|
||||||
|
msgstr "Alternativen-Kandidatenlimit"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.mvd_tcg_deck_view_form_openai_inherit
|
||||||
|
msgid "Alternative Suggestions"
|
||||||
|
msgstr "Alternativvorschläge"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.mvd_tcg_deck_view_form_openai_inherit
|
||||||
|
msgid "Analyze Card Roles"
|
||||||
|
msgstr "Kartenrollen analysieren"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.mvd_tcg_deck_view_form_openai_inherit
|
||||||
|
msgid "Analyze Deck"
|
||||||
|
msgstr "Deck analysieren"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model,name:mvd_tcg_mtg_deck_openai.model_res_config_settings
|
||||||
|
msgid "Config Settings"
|
||||||
|
msgstr "Konfiguration"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "Configure an OpenAI API key in TCG Settings first."
|
||||||
|
msgstr "Konfiguriere zuerst einen OpenAI-API-Schlüssel in den TCG-Einstellungen."
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.report_mvd_tcg_deck_document_openai_inherit
|
||||||
|
msgid "Deck Analysis"
|
||||||
|
msgstr "Deckanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.mvd_tcg_deck_view_form_openai_inherit
|
||||||
|
msgid "Deck Fill"
|
||||||
|
msgstr "Deck auffüllen"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_res_config_settings__mtg_openai_fill_batch_size
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid "Deck Fill Batch Size"
|
||||||
|
msgstr "Batch-Größe für Deck-Auffüllen"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_res_config_settings__mtg_openai_fill_candidate_limit
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid "Deck Fill Candidate Limit"
|
||||||
|
msgstr "Kandidatenlimit für Deck-Auffüllen"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid ""
|
||||||
|
"Default model used for deck summaries, role tagging, deck fill, and "
|
||||||
|
"alternative suggestions."
|
||||||
|
msgstr ""
|
||||||
|
"Standardmodell für Deck-Zusammenfassungen, Rollentags, Deck-Auffüllen und "
|
||||||
|
"Alternativvorschläge."
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__display_name
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck_line__display_name
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_res_config_settings__display_name
|
||||||
|
msgid "Display Name"
|
||||||
|
msgstr "Anzeigename"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields.selection,name:mvd_tcg_mtg_deck_openai.selection__mvd_tcg_deck__mtg_openai_alternative_state__failed
|
||||||
|
#: model:ir.model.fields.selection,name:mvd_tcg_mtg_deck_openai.selection__mvd_tcg_deck__mtg_openai_analysis_state__failed
|
||||||
|
#: model:ir.model.fields.selection,name:mvd_tcg_mtg_deck_openai.selection__mvd_tcg_deck__mtg_openai_fill_state__failed
|
||||||
|
#: model:ir.model.fields.selection,name:mvd_tcg_mtg_deck_openai.selection__mvd_tcg_deck__mtg_openai_role_analysis_state__failed
|
||||||
|
msgid "Failed"
|
||||||
|
msgstr "Fehlgeschlagen"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.mvd_tcg_deck_view_form_openai_inherit
|
||||||
|
msgid "Fill Deck"
|
||||||
|
msgstr "Deck auffüllen"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.mvd_tcg_deck_view_form_openai_inherit
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.report_mvd_tcg_deck_document_openai_inherit
|
||||||
|
msgid "Game Plan"
|
||||||
|
msgstr "Spielplan"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid "How many deck lines are sent in one role-analysis request."
|
||||||
|
msgstr "Wie viele Deckzeilen in einer Rollen-Analyse-Anfrage gesendet werden."
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__id
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck_line__id
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_res_config_settings__id
|
||||||
|
msgid "ID"
|
||||||
|
msgstr "ID"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid "Maximum number of cards the AI may add in one fill iteration."
|
||||||
|
msgstr "Maximale Anzahl an Karten, die die KI in einer Auffüllrunde hinzufügen darf."
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid ""
|
||||||
|
"Maximum number of in-system candidate cards considered for AI-assisted deck "
|
||||||
|
"fill."
|
||||||
|
msgstr ""
|
||||||
|
"Maximale Anzahl an im System verfügbaren Kandidatenkarten für das "
|
||||||
|
"KI-gestützte Deck-Auffüllen."
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid ""
|
||||||
|
"Maximum number of in-system replacement candidates passed for one "
|
||||||
|
"problematic deck line."
|
||||||
|
msgstr ""
|
||||||
|
"Maximale Anzahl an im System verfügbaren Ersatzkandidaten für eine "
|
||||||
|
"problematische Deckzeile."
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "Missing configured deck roles for: %s"
|
||||||
|
msgstr "Fehlende konfigurierte Deckrollen für: %s"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_res_config_settings__mtg_openai_model_name
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid "Default Model"
|
||||||
|
msgstr "Standardmodell"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_alternative_last_analyzed_at
|
||||||
|
msgid "Last Alternative Analysis"
|
||||||
|
msgstr "Letzte Alternativanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_alternative_last_error
|
||||||
|
msgid "Last Alternative Analysis Error"
|
||||||
|
msgstr "Letzter Fehler der Alternativanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_alternative_last_lang
|
||||||
|
msgid "Alternative Analysis Language"
|
||||||
|
msgstr "Sprache der Alternativanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_alternative_last_model
|
||||||
|
msgid "Alternative Analysis Model"
|
||||||
|
msgstr "Modell der Alternativanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_alternative_last_prompt
|
||||||
|
msgid "Last Alternative Analysis Prompt"
|
||||||
|
msgstr "Letzter Prompt der Alternativanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_alternative_last_response
|
||||||
|
msgid "Last Alternative Analysis Response"
|
||||||
|
msgstr "Letzte Antwort der Alternativanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_alternative_state
|
||||||
|
msgid "Alternative Analysis Status"
|
||||||
|
msgstr "Status der Alternativanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_alternative_suggestions
|
||||||
|
msgid "Alternative Suggestions"
|
||||||
|
msgstr "Alternativvorschläge"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_analysis_state
|
||||||
|
msgid "Deck Analysis Status"
|
||||||
|
msgstr "Status der Deckanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_commander_summary
|
||||||
|
msgid "Commander Summary"
|
||||||
|
msgstr "Commander-Zusammenfassung"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_fill_last_analyzed_at
|
||||||
|
msgid "Last Deck Fill"
|
||||||
|
msgstr "Letzte Deck-Auffüllung"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_fill_last_error
|
||||||
|
msgid "Last Deck Fill Error"
|
||||||
|
msgstr "Letzter Fehler beim Deck-Auffüllen"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_fill_last_lang
|
||||||
|
msgid "Deck Fill Language"
|
||||||
|
msgstr "Sprache der Deck-Auffüllung"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_fill_last_model
|
||||||
|
msgid "Deck Fill Model"
|
||||||
|
msgstr "Modell für Deck-Auffüllung"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_fill_last_prompt
|
||||||
|
msgid "Last Deck Fill Prompt"
|
||||||
|
msgstr "Letzter Prompt für Deck-Auffüllung"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_fill_last_response
|
||||||
|
msgid "Last Deck Fill Response"
|
||||||
|
msgstr "Letzte Antwort für Deck-Auffüllung"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_fill_state
|
||||||
|
msgid "Deck Fill Status"
|
||||||
|
msgstr "Status der Deck-Auffüllung"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_fill_summary
|
||||||
|
msgid "Deck Fill Summary"
|
||||||
|
msgstr "Zusammenfassung der Deck-Auffüllung"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_gameplan
|
||||||
|
msgid "Game Plan"
|
||||||
|
msgstr "Spielplan"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_last_analyzed_at
|
||||||
|
msgid "Last Deck Analysis"
|
||||||
|
msgstr "Letzte Deckanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_last_error
|
||||||
|
msgid "Last Analysis Error"
|
||||||
|
msgstr "Letzter Analysefehler"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_last_lang
|
||||||
|
msgid "Analysis Language"
|
||||||
|
msgstr "Analysesprache"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_last_model
|
||||||
|
msgid "Analysis Model"
|
||||||
|
msgstr "Analysemodell"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_last_prompt
|
||||||
|
msgid "Last Analysis Prompt"
|
||||||
|
msgstr "Letzter Analyse-Prompt"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_last_response
|
||||||
|
msgid "Last Analysis Response"
|
||||||
|
msgstr "Letzte Analyseantwort"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_pilot_tips
|
||||||
|
msgid "Pilot Tips"
|
||||||
|
msgstr "Pilottipps"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_risk_notes
|
||||||
|
msgid "Risk Notes"
|
||||||
|
msgstr "Risikohinweise"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_role_analysis_state
|
||||||
|
msgid "Role Analysis Status"
|
||||||
|
msgstr "Status der Rollenanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_role_last_analyzed_at
|
||||||
|
msgid "Last Role Analysis"
|
||||||
|
msgstr "Letzte Rollenanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_role_last_error
|
||||||
|
msgid "Last Role Analysis Error"
|
||||||
|
msgstr "Letzter Fehler der Rollenanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_role_last_lang
|
||||||
|
msgid "Role Analysis Language"
|
||||||
|
msgstr "Sprache der Rollenanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_role_last_model
|
||||||
|
msgid "Role Analysis Model"
|
||||||
|
msgstr "Modell der Rollenanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_role_last_prompt
|
||||||
|
msgid "Last Role Analysis Prompt"
|
||||||
|
msgstr "Letzter Prompt der Rollenanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck__mtg_openai_role_last_response
|
||||||
|
msgid "Last Role Analysis Response"
|
||||||
|
msgstr "Letzte Antwort der Rollenanalyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_mvd_tcg_deck_line__mtg_openai_role_rationale
|
||||||
|
msgid "Role Rationale"
|
||||||
|
msgstr "Rollenbegründung"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields.selection,name:mvd_tcg_mtg_deck_openai.selection__mvd_tcg_deck__mtg_openai_alternative_state__empty
|
||||||
|
#: model:ir.model.fields.selection,name:mvd_tcg_mtg_deck_openai.selection__mvd_tcg_deck__mtg_openai_analysis_state__empty
|
||||||
|
#: model:ir.model.fields.selection,name:mvd_tcg_mtg_deck_openai.selection__mvd_tcg_deck__mtg_openai_fill_state__empty
|
||||||
|
#: model:ir.model.fields.selection,name:mvd_tcg_mtg_deck_openai.selection__mvd_tcg_deck__mtg_openai_role_analysis_state__empty
|
||||||
|
msgid "Not Analyzed"
|
||||||
|
msgstr "Nicht analysiert"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_res_config_settings__mtg_openai_api_base_url
|
||||||
|
msgid "API Base URL"
|
||||||
|
msgstr "API-Basis-URL"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid "OpenAI Analysis"
|
||||||
|
msgstr "OpenAI-Analyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_res_config_settings__mtg_openai_request_timeout_seconds
|
||||||
|
msgid "OpenAI Request Timeout (s)"
|
||||||
|
msgstr "OpenAI-Request-Timeout (s)"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI alternative suggestions are only available for Magic decks."
|
||||||
|
msgstr "OpenAI-Alternativvorschläge sind nur für Magic-Decks verfügbar."
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI attempted to add multiple copies of a singleton card."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI attempted to add too many cards in one batch."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI card analysis is only available for Magic decks."
|
||||||
|
msgstr "Die OpenAI-Kartenanalyse ist nur für Magic-Decks verfügbar."
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI deck analysis is only available for Magic decks."
|
||||||
|
msgstr "Die OpenAI-Deckanalyse ist nur für Magic-Decks verfügbar."
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI deck fill is only available for Magic decks."
|
||||||
|
msgstr "Das OpenAI-Deck-Auffüllen ist nur für Magic-Decks verfügbar."
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI did not return alternative rows for every issue line."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI did not return role assignments for every deck line."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI returned a card outside the allowed pool."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI returned a role analysis for an unknown deck line."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI returned alternatives for an unknown deck line."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI returned an invalid fill quantity."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI returned an unsupported replacement candidate."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI returned an unsupported role key: %(role_key)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI returned duplicate alternative rows for one deck line."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI returned duplicate role analysis rows for one deck line."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "OpenAI returned the same fill card more than once."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid ""
|
||||||
|
"Override the OpenAI API base URL only for special environments or proxies."
|
||||||
|
msgstr ""
|
||||||
|
"Die OpenAI-API-Basis-URL nur für spezielle Umgebungen oder Proxys "
|
||||||
|
"überschreiben."
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.mvd_tcg_deck_view_form_openai_inherit
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.report_mvd_tcg_deck_document_openai_inherit
|
||||||
|
msgid "Pilot Tips"
|
||||||
|
msgstr "Pilothinweise"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields.selection,name:mvd_tcg_mtg_deck_openai.selection__mvd_tcg_deck__mtg_openai_alternative_state__done
|
||||||
|
#: model:ir.model.fields.selection,name:mvd_tcg_mtg_deck_openai.selection__mvd_tcg_deck__mtg_openai_analysis_state__done
|
||||||
|
#: model:ir.model.fields.selection,name:mvd_tcg_mtg_deck_openai.selection__mvd_tcg_deck__mtg_openai_fill_state__done
|
||||||
|
#: model:ir.model.fields.selection,name:mvd_tcg_mtg_deck_openai.selection__mvd_tcg_deck__mtg_openai_role_analysis_state__done
|
||||||
|
msgid "Ready"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid "Request Timeout"
|
||||||
|
msgstr "Request-Timeout"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.mvd_tcg_deck_view_form_openai_inherit
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.report_mvd_tcg_deck_document_openai_inherit
|
||||||
|
msgid "Risk Notes"
|
||||||
|
msgstr "Risikohinweise"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model.fields,field_description:mvd_tcg_mtg_deck_openai.field_res_config_settings__mtg_openai_role_batch_size
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid "Role Analysis Batch Size"
|
||||||
|
msgstr "Batch-Größe der Rollen-Analyse"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "Select a supported MTG format before using deck fill."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "Select at least one commander card first."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid ""
|
||||||
|
"Stored in system parameters and used for OpenAI-backed MTG deck analysis."
|
||||||
|
msgstr ""
|
||||||
|
"Wird in den Systemparametern gespeichert und für die OpenAI-gestützte "
|
||||||
|
"MTG-Deckanalyse verwendet."
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.mvd_tcg_deck_view_form_openai_inherit
|
||||||
|
msgid "Suggest Alternatives"
|
||||||
|
msgstr "Alternativen vorschlagen"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model,name:mvd_tcg_mtg_deck_openai.model_mvd_tcg_deck
|
||||||
|
msgid "TCG Deck"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model:ir.model,name:mvd_tcg_mtg_deck_openai.model_mvd_tcg_deck_line
|
||||||
|
msgid "TCG Deck Line"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.mvd_tcg_deck_view_form_openai_inherit
|
||||||
|
msgid "Technical"
|
||||||
|
msgstr "Technisch"
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "The mainboard is already full for the selected format."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "This deck does not have a mainboard yet."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "This deck has no cards to analyze."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#. odoo-python
|
||||||
|
#: code:addons/mvd_tcg_mtg_deck_openai/models/mvd_tcg_deck.py:0
|
||||||
|
msgid "This deck has no replaceable issue lines right now."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid "Timeout in seconds for OpenAI responses requests."
|
||||||
|
msgstr "Timeout in Sekunden für OpenAI-Responses-Anfragen."
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid "gpt-5-mini"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. module: mvd_tcg_mtg_deck_openai
|
||||||
|
#: model_terms:ir.ui.view,arch_db:mvd_tcg_mtg_deck_openai.res_config_settings_view_form_mvd_tcg_mtg_deck_openai
|
||||||
|
msgid "sk-..."
|
||||||
|
msgstr ""
|
||||||
3
models/__init__.py
Normal file
3
models/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from . import mvd_tcg_deck
|
||||||
|
from . import mvd_tcg_deck_line
|
||||||
|
from . import res_config_settings
|
||||||
9
models/constants.py
Normal file
9
models/constants.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
"""Shared constants for the MTG OpenAI analysis layer."""
|
||||||
|
|
||||||
|
DEFAULT_MTG_OPENAI_MODEL_NAME = "gpt-5-mini"
|
||||||
|
DEFAULT_MTG_OPENAI_API_BASE_URL = "https://api.openai.com/v1"
|
||||||
|
DEFAULT_MTG_OPENAI_REQUEST_TIMEOUT_SECONDS = 120
|
||||||
|
DEFAULT_MTG_OPENAI_ROLE_BATCH_SIZE = 24
|
||||||
|
DEFAULT_MTG_OPENAI_FILL_CANDIDATE_LIMIT = 240
|
||||||
|
DEFAULT_MTG_OPENAI_FILL_BATCH_SIZE = 24
|
||||||
|
DEFAULT_MTG_OPENAI_ALTERNATIVE_CANDIDATE_LIMIT = 36
|
||||||
2103
models/mvd_tcg_deck.py
Normal file
2103
models/mvd_tcg_deck.py
Normal file
File diff suppressed because it is too large
Load Diff
14
models/mvd_tcg_deck_line.py
Normal file
14
models/mvd_tcg_deck_line.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
"""OpenAI fields for MTG deck lines."""
|
||||||
|
|
||||||
|
from odoo import fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class MvdTcgDeckLine(models.Model):
|
||||||
|
"""Extend deck lines with persisted OpenAI role-analysis output."""
|
||||||
|
|
||||||
|
_inherit = "mvd.tcg.deck.line"
|
||||||
|
|
||||||
|
mtg_openai_role_rationale = fields.Text(
|
||||||
|
readonly=True,
|
||||||
|
copy=False,
|
||||||
|
)
|
||||||
71
models/res_config_settings.py
Normal file
71
models/res_config_settings.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
"""Settings for the OpenAI-backed MTG deck analysis layer."""
|
||||||
|
|
||||||
|
from odoo import api, fields, models
|
||||||
|
from odoo.exceptions import UserError, ValidationError
|
||||||
|
|
||||||
|
from .constants import (
|
||||||
|
DEFAULT_MTG_OPENAI_API_BASE_URL,
|
||||||
|
DEFAULT_MTG_OPENAI_ALTERNATIVE_CANDIDATE_LIMIT,
|
||||||
|
DEFAULT_MTG_OPENAI_FILL_BATCH_SIZE,
|
||||||
|
DEFAULT_MTG_OPENAI_FILL_CANDIDATE_LIMIT,
|
||||||
|
DEFAULT_MTG_OPENAI_MODEL_NAME,
|
||||||
|
DEFAULT_MTG_OPENAI_REQUEST_TIMEOUT_SECONDS,
|
||||||
|
DEFAULT_MTG_OPENAI_ROLE_BATCH_SIZE,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ResConfigSettings(models.TransientModel):
|
||||||
|
"""Expose OpenAI deck-analysis defaults through Odoo settings."""
|
||||||
|
|
||||||
|
_inherit = "res.config.settings"
|
||||||
|
|
||||||
|
mtg_openai_api_key = fields.Char(
|
||||||
|
string="API Key",
|
||||||
|
config_parameter="mvd_tcg_mtg_deck_openai.api_key",
|
||||||
|
)
|
||||||
|
mtg_openai_model_name = fields.Char(
|
||||||
|
string="Default Model",
|
||||||
|
config_parameter="mvd_tcg_mtg_deck_openai.model_name",
|
||||||
|
default=DEFAULT_MTG_OPENAI_MODEL_NAME,
|
||||||
|
)
|
||||||
|
mtg_openai_api_base_url = fields.Char(
|
||||||
|
string="OpenAI API Base URL",
|
||||||
|
config_parameter="mvd_tcg_mtg_deck_openai.api_base_url",
|
||||||
|
default=DEFAULT_MTG_OPENAI_API_BASE_URL,
|
||||||
|
)
|
||||||
|
mtg_openai_request_timeout_seconds = fields.Integer(
|
||||||
|
string="OpenAI Request Timeout (s)",
|
||||||
|
config_parameter="mvd_tcg_mtg_deck_openai.request_timeout_seconds",
|
||||||
|
default=DEFAULT_MTG_OPENAI_REQUEST_TIMEOUT_SECONDS,
|
||||||
|
)
|
||||||
|
mtg_openai_role_batch_size = fields.Integer(
|
||||||
|
string="Role Analysis Batch Size",
|
||||||
|
config_parameter="mvd_tcg_mtg_deck_openai.role_batch_size",
|
||||||
|
default=DEFAULT_MTG_OPENAI_ROLE_BATCH_SIZE,
|
||||||
|
)
|
||||||
|
mtg_openai_fill_candidate_limit = fields.Integer(
|
||||||
|
string="Deck Fill Candidate Limit",
|
||||||
|
config_parameter="mvd_tcg_mtg_deck_openai.fill_candidate_limit",
|
||||||
|
default=DEFAULT_MTG_OPENAI_FILL_CANDIDATE_LIMIT,
|
||||||
|
)
|
||||||
|
mtg_openai_fill_batch_size = fields.Integer(
|
||||||
|
string="Deck Fill Batch Size",
|
||||||
|
config_parameter="mvd_tcg_mtg_deck_openai.fill_batch_size",
|
||||||
|
default=DEFAULT_MTG_OPENAI_FILL_BATCH_SIZE,
|
||||||
|
)
|
||||||
|
mtg_openai_alternative_candidate_limit = fields.Integer(
|
||||||
|
string="Alternative Candidate Limit",
|
||||||
|
config_parameter="mvd_tcg_mtg_deck_openai.alternative_candidate_limit",
|
||||||
|
default=DEFAULT_MTG_OPENAI_ALTERNATIVE_CANDIDATE_LIMIT,
|
||||||
|
)
|
||||||
|
|
||||||
|
@api.constrains("mtg_openai_api_base_url")
|
||||||
|
def _check_mtg_openai_api_base_url(self):
|
||||||
|
"""Restrict the OpenAI connector to the official HTTPS API host."""
|
||||||
|
for settings in self:
|
||||||
|
try:
|
||||||
|
self.env["mvd.tcg.deck"]._mtg_openai_validate_base_url(
|
||||||
|
settings.mtg_openai_api_base_url
|
||||||
|
)
|
||||||
|
except UserError as exc:
|
||||||
|
raise ValidationError(str(exc)) from exc
|
||||||
48
report/mvd_tcg_mtg_deck_report_templates.xml
Normal file
48
report/mvd_tcg_mtg_deck_report_templates.xml
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<template
|
||||||
|
id="report_mvd_tcg_deck_document_openai_inherit"
|
||||||
|
inherit_id="mvd_tcg_deck.report_mvd_tcg_deck_document"
|
||||||
|
>
|
||||||
|
<xpath expr="//div[hasclass('o_mvd_tcg_report_board_header')]" position="after">
|
||||||
|
<div
|
||||||
|
t-if="section['board'].code == 'command_zone' and doc.mtg_openai_commander_summary"
|
||||||
|
class="o_mvd_tcg_report_section o_mvd_tcg_report_section_emphasis"
|
||||||
|
style="margin-bottom: 10px;"
|
||||||
|
>
|
||||||
|
<h3 class="o_mvd_tcg_report_section_title">Deck Analysis</h3>
|
||||||
|
<div t-field="doc.mtg_openai_commander_summary"/>
|
||||||
|
<table
|
||||||
|
t-if="doc.mtg_openai_gameplan or doc.mtg_openai_pilot_tips or doc.mtg_openai_risk_notes"
|
||||||
|
class="o_mvd_tcg_report_snapshot"
|
||||||
|
style="margin-top: 8px;"
|
||||||
|
>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td t-if="doc.mtg_openai_gameplan">
|
||||||
|
<div class="o_mvd_tcg_report_snapshot_block">
|
||||||
|
<h4>Game Plan</h4>
|
||||||
|
<div t-field="doc.mtg_openai_gameplan"/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td t-if="doc.mtg_openai_pilot_tips">
|
||||||
|
<div class="o_mvd_tcg_report_snapshot_block">
|
||||||
|
<h4>Pilot Tips</h4>
|
||||||
|
<div t-field="doc.mtg_openai_pilot_tips"/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div
|
||||||
|
t-if="doc.mtg_openai_risk_notes"
|
||||||
|
class="o_mvd_tcg_report_snapshot_block"
|
||||||
|
style="margin-top: 8px;"
|
||||||
|
>
|
||||||
|
<h4>Risk Notes</h4>
|
||||||
|
<div t-field="doc.mtg_openai_risk_notes"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
</odoo>
|
||||||
169
views/mvd_tcg_mtg_deck_views.xml
Normal file
169
views/mvd_tcg_mtg_deck_views.xml
Normal 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>
|
||||||
74
views/res_config_settings_views.xml
Normal file
74
views/res_config_settings_views.xml
Normal 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>
|
||||||
Reference in New Issue
Block a user