Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/prompts/ai-translation-user.prompt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ messages:
Please read the translation file "{{translation_file}}" and translate all the strings from English to {{language}}.

The file contains strings in the format "line_number:English text" - please translate only the text after the colon while preserving the exact line number and colon format.

Translation strings to process:
{{translation_content}}
101 changes: 67 additions & 34 deletions .github/workflows/ai-translation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ jobs:
matrix:
include: ${{ fromJson(needs.extract_strings.outputs.translation-matrix) }}
fail-fast: false # Continue processing other languages even if one fails
max-parallel: 5 # Limit concurrent AI requests
max-parallel: 1 # Limit concurrent AI requests to avoid rate limiting

steps:
- name: Harden the runner (Audit all outbound calls)
Expand Down Expand Up @@ -236,6 +236,15 @@ jobs:
echo "📊 Translation file size: $file_size bytes"
echo "✅ Translation file validation completed successfully"

- name: Prepare translation content
id: translation_content
run: |
# Read file and indent each line by 2 spaces (except the first)
awk 'NR==1 {print} NR>1 {print " " $0}' "${{ matrix.file }}" > indented_content.txt
echo "content<<EOF" >> $GITHUB_OUTPUT
cat indented_content.txt >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

- name: Run AI translation
id: ai_translate
uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v2.0.4
Expand All @@ -246,10 +255,8 @@ jobs:
language: ${{ matrix.language }}
lang_code: ${{ matrix.lang_code }}
translation_file: ${{ matrix.file }}
file_input: |
translation_content: ${{ matrix.file }}
enable-github-mcp: true
github-mcp-toolsets: "context,repos"
translation_content: |
${{ steps.translation_content.outputs.content }}
model: openai/gpt-4.1
max-tokens: 8000
token: ${{ secrets.AMC_COPILOT_TOKEN_CLASSIC }}
Expand Down Expand Up @@ -308,22 +315,32 @@ jobs:
# Save the AI response back to the original translation file
if [ "${{ steps.check_translation.outputs.output_method }}" = "file" ]; then
echo "📄 Using response file: ${{ steps.ai_translate.outputs.response-file }}"
cp "${{ steps.ai_translate.outputs.response-file }}" "${{ matrix.file }}"
cp "${{ steps.ai_translate.outputs.response-file }}" "${{ matrix.file }}.raw"
elif [ "${{ steps.check_translation.outputs.output_method }}" = "content" ]; then
echo "📝 Using response content"
echo "${{ steps.ai_translate.outputs.response }}" > "${{ matrix.file }}"
echo "${{ steps.ai_translate.outputs.response }}" > "${{ matrix.file }}.raw"
else
echo "❌ Unexpected output method: ${{ steps.check_translation.outputs.output_method }}"
exit 1
fi

# Validate the saved file
# Clean up AI output: keep only lines starting with number followed by colon
echo "🧹 Cleaning AI output..."
grep -E '^[0-9]+:' "${{ matrix.file }}.raw" > "${{ matrix.file }}" || {
echo "❌ Failed to extract valid translations from AI output"
echo "Raw output preview:"
head -20 "${{ matrix.file }}.raw"
exit 1
}

# Validate the cleaned file
if [ -f "${{ matrix.file }}" ] && [ -s "${{ matrix.file }}" ]; then
echo "✅ AI translation saved successfully for ${{ matrix.language }} (${{ matrix.file }})"
echo "📊 File size: $(wc -c < "${{ matrix.file }}") bytes"
echo "📊 Line count: $(wc -l < "${{ matrix.file }}") lines"
echo "✅ AI translation saved and cleaned successfully for ${{ matrix.language }}"
echo "📊 Raw file size: $(wc -c < "${{ matrix.file }}.raw") bytes"
echo "📊 Cleaned file size: $(wc -c < "${{ matrix.file }}") bytes"
echo "📊 Valid translation lines: $(wc -l < "${{ matrix.file }}") lines"
else
echo "❌ Translation file is empty or missing: ${{ matrix.file }}"
echo "❌ Translation file is empty or missing after cleanup: ${{ matrix.file }}"
exit 1
fi

Expand Down Expand Up @@ -437,7 +454,10 @@ jobs:

- name: Insert AI translations into .po files
if: needs.extract_strings.outputs.translations-to-process == 'true'
shell: bash # Don't use -e flag to prevent premature exit
run: |
set -x # Enable command tracing for debugging

# Check if we have any translated files
if ls missing_translations_*.txt 1> /dev/null 2>&1; then
echo "📥 Processing AI translations..."
Expand All @@ -450,12 +470,12 @@ jobs:
if [ -f "$file" ]; then
if grep -q "# Translation failed" "$file" 2>/dev/null; then
echo "⚠️ Found failed translation: $file"
((failed_translations++))
failed_translations=$((failed_translations + 1))
# Remove failed translation files so they don't get processed
rm "$file"
else
echo "✅ Found successful translation: $file"
((successful_translations++))
successful_translations=$((successful_translations + 1))
fi
fi
done
Expand All @@ -466,8 +486,39 @@ jobs:

if [ $successful_translations -gt 0 ]; then
echo "🔄 Processing successful translations with insert_missing_translations.py"
python insert_missing_translations.py
echo "✅ AI translations inserted into .po files"

# Show files that will be processed
echo "Files to process:"
ls -lh missing_translations_*.txt

# Validate file format before processing
echo "Validating translation file format..."
for file in missing_translations_*.txt; do
echo "Checking $file:"
if grep -qE '^[0-9]+:' "$file"; then
echo "✅ File format is valid"
else
echo "❌ ERROR: File $file does not contain valid translation lines (format: number:text)"
echo "File contents:"
cat "$file"
exit 1
fi

# Show file preview
echo "First 5 lines of $file:"
head -5 "$file"
echo "---"
done

# Run with full error output captured
echo "Running insert_missing_translations.py..."
if python insert_missing_translations.py 2>&1; then
echo "✅ AI translations inserted into .po files"
else
exit_code=$?
echo "❌ insert_missing_translations.py failed with exit code $exit_code"
exit $exit_code
fi
else
echo "⚠️ No successful translations to process"
fi
Expand Down Expand Up @@ -536,14 +587,7 @@ jobs:

🤖 **AI-Powered Translation Applied with Enhanced Matrix Processing**:
- Automatically extracted missing translations using `extract_missing_translations.py`
- Used GitHub Actions matrix strategy to process numbered files in parallel
- Applied AI-powered translations using GitHub Models (GPT-4o) for multiple languages
- **GITHUB PROMPT.YML FORMAT**: Using official GitHub prompt.yml template format with separated files
- **SEPARATED PROMPT.YML FILES**: Organized in .github/prompts/ directory for better structure
- **CLEAN ORGANIZATION**: ai-translation-system.prompt.yml and ai-translation-user.prompt.yml separated from workflows
- **PERSONAL ACCESS TOKEN**: Using amilcarlucas PAT for GitHub MCP access instead of GITHUB_TOKEN
- **GITHUB MCP ENABLED**: AI can read translation files directly from repository using Model Context Protocol
- **FILE-BASED PROMPTS**: AI reads translation files directly instead of embedding content in YAML prompts
- Supports processing unlimited translations per language with automatic chunking
- Inserted translated strings into .po files using `insert_missing_translations.py`
- Compiled binary .mo files for immediate use
Expand All @@ -553,23 +597,12 @@ jobs:
**Languages processed**: Portuguese (pt), German (de), Italian (it), Japanese (ja), Chinese Simplified (zh_CN)

**Enhanced Matrix Processing & Scaling**:
- ✅ **Parallel processing** of translation files for better performance
- ✅ **Automatic chunking** when >50 strings per language (configurable)
- ✅ **Robust error handling** for failed AI translation requests with detailed debugging
- ✅ **File validation** before and after AI processing
- ✅ **Consistent terminology** guidelines applied across all chunks for each language
- Robust error handling for failed AI translation requests

**Technical Improvements Made**:
- 🔧 **Organized prompt structure**: Moved prompt files to .github/prompts/ directory to avoid confusion with workflows
- 🔧 **GitHub MCP enabled**: AI can read translation files directly from repository using Model Context Protocol
- 🔧 **Separated prompt architecture**: System prompt and user prompt in separate files for better maintainability
- 🔧 **File-based AI prompts**: AI reads translation files directly, eliminating YAML content embedding issues
- 🔧 **Reusable system prompts**: System prompt can be reused across different translation tasks
- 🔧 **Enhanced reliability**: No more YAML syntax issues from embedded content with special characters
- 🔧 **Better scalability**: File-based approach handles large translation batches without prompt size limits
- 🔧 **403 error fix**: Enabled GitHub MCP to resolve permission issues when reading repository files

**Translation Guidelines Applied**:
- Technical aviation/drone context preservation
- Formal register for technical documentation
Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ repos:
- tomli

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.6
rev: v0.14.7
hooks:
- id: ruff-check
args: [ --fix ]
Expand All @@ -56,7 +56,7 @@ repos:
# entry: markdown-link-check

- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.45.0
rev: v0.46.0
hooks:
- id: markdownlint
args: ['--config', '.markdownlint.yaml']
Expand Down Expand Up @@ -94,7 +94,7 @@ repos:
- id: reuse-lint-file

- repo: https://github.com/gitleaks/gitleaks
rev: v8.29.1
rev: v8.30.0
hooks:
- id: gitleaks

Expand Down
4 changes: 2 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ We need contributors to help realize this roadmap! Here's how you can get involv
- 2025.09.04 - Added [empty, unopinionated vehicle templates](https://github.com/ArduPilot/MethodicConfigurator/releases/tag/v2.1.0)
- 2025.08.28 - Option to [reset all parameters to their defaults before starting the configuration](https://github.com/ArduPilot/MethodicConfigurator/releases/tag/v2.0.6)
- 2025.07.16 - [YouTube beginners Tutorial](https://www.youtube.com/watch?v=tM8EznlNhgs&list=PL1oa0qoJ9W_89eMcn4x2PB6o3fyPbheA9)
- 2025.06.15 - The tunning guide is the [single most liked post in the ArduPilot forum](https://discuss.ardupilot.org/badges/20/great-topic)
- 2025.06.15 - The tuning guide is the [single most liked post in the ArduPilot forum](https://discuss.ardupilot.org/badges/20/great-topic)
- 2025.04.26 - [First YouTube video Tutorial](https://www.youtube.com/watch?v=47RjQ_GarvE)
- 2025.04.02 - Initial ArduPlane template and support
- 2025.02.20 - [AI powered, ArduPilot trained chatbot](https://gurubase.io/g/ardupilot)
- 2025.01.27 - [40% test coverage](https://coveralls.io/builds/71941955)
- 2024.12.18 - Reached all initially defined project features
- 2024.03.14 - [First public release](https://discuss.ardupilot.org/t/new-ardupilot-methodic-configurator-gui/115038)
- 2023.12.15 - Posted the [tunning guide](https://discuss.ardupilot.org/t/how-to-methodically-configure-and-tune-any-arducopter/110842)
- 2023.12.15 - Posted the [tuning guide](https://discuss.ardupilot.org/t/how-to-methodically-configure-and-tune-any-arducopter/110842)

<!-- Gurubase Widget -->
<script async src="https://widget.gurubase.io/widget.latest.min.js"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ msgstr "Validierungsschema konnte nicht geladen werden"
msgid "Invalid JSON file '%s': %s"
msgstr "Ungültige JSON-Datei '%s': %s"

msgstr "Validierungsfehler"
#: ardupilot_methodic_configurator/backend_filesystem_json_with_schema.py:103
msgid "File '%s' not found in %s."
msgstr "Datei '%s' nicht gefunden in %s."
Expand Down Expand Up @@ -811,6 +812,7 @@ msgstr "Autopilot-Typ {self.info.autopilot}"
msgid ""
"Vehicle type: {self.info.mav_type} running {self.info.vehicle_type} firmware"
msgstr ""
msgstr "Verbindung mit System-ID %s, Komponenten-ID %s hergestellt."
"Fahrzeugtyp: {self.info.mav_type}, der {self.info.vehicle_type} Firmware "
"läuft"

Expand Down Expand Up @@ -3902,10 +3904,12 @@ msgstr "'{param_name}' wurde in der apm.pdef.xml Datei nicht gefunden."

#: ardupilot_methodic_configurator/data_model_parameter_editor.py:1563
msgid ""
msgstr "Parameter nicht gefunden"
"Can not add parameter when no FC is connected and no apm.pdef.xml file "
"exists."
msgstr ""
"Parameter kann nicht hinzugefügt werden, wenn kein FC verbunden ist und "
msgstr "Parameter {param_name} konnte nicht gefunden werden."
"keine apm.pdef.xml Datei existiert."

#: ardupilot_methodic_configurator/data_model_parameter_editor.py:1703
Expand Down Expand Up @@ -4591,6 +4595,7 @@ msgstr "Anwendungssymbol konnte nicht geladen werden: %s"
#: ardupilot_methodic_configurator/frontend_tkinter_base_window.py:337
msgid "Image filepath cannot be empty"
msgstr "Bilddateipfad darf nicht leer sein"
msgstr "Allgemeiner AMC-Workflow"

#: ardupilot_methodic_configurator/frontend_tkinter_base_window.py:341
msgid "Image height must be positive"
Expand Down Expand Up @@ -5195,6 +5200,7 @@ msgstr "In Sequenz testen"

#: ardupilot_methodic_configurator/frontend_tkinter_motor_test.py:227
msgid "Stop All Motors"
msgstr "Parameter konnten nicht heruntergeladen werden"
msgstr "Alle Motoren stoppen"

#: ardupilot_methodic_configurator/frontend_tkinter_motor_test.py:230
Expand Down Expand Up @@ -6121,7 +6127,7 @@ msgstr "Abgeleiteter Parameter"
#: ardupilot_methodic_configurator/frontend_tkinter_parameter_editor_table.py:516
msgid ""
"Parameter %s changed, will later ask if change(s) should be saved to file."
msgstr ""
msgstr "Unbekannter Fehler."
"Parameter %s geändert, es wird später gefragt, ob die Änderung(en) in die "
"Datei gespeichert werden sollen."

Expand Down Expand Up @@ -6571,43 +6577,53 @@ msgid "Format version"
msgstr "Formatversion"

#: ardupilot_methodic_configurator/vehicle_components.py:32
msgstr "Dies ist keine Bodenstation und hat einen anderen Workflow:"
msgid "Frame"
msgstr "Rahmen"

#: ardupilot_methodic_configurator/vehicle_components.py:33
msgstr "ArduPilot Methodischer Konfigurator - Workflow"
msgid "GNSS Receiver"
msgstr "GNSS-Empfänger"

#: ardupilot_methodic_configurator/vehicle_components.py:35
msgstr "[Bild nicht gefunden: AMC_general_workflow.png]"
msgid "Manufacturer"
msgstr "Hersteller"

#: ardupilot_methodic_configurator/vehicle_components.py:36
msgstr "siehe"
msgid "Model"
msgstr "Modell"

#: ardupilot_methodic_configurator/vehicle_components.py:37
msgstr "Schnellstartanleitung"
msgid "Motors"
msgstr "Motoren"

#: ardupilot_methodic_configurator/vehicle_components.py:38
msgid "Notes"
msgstr ","
msgstr "Notizen"

#: ardupilot_methodic_configurator/vehicle_components.py:39
msgid "Number of cells"
msgstr "YouTube-Tutorials"
msgstr "Anzahl der Zellen"

#: ardupilot_methodic_configurator/vehicle_components.py:40
msgid "Poles"
msgstr "Anwendungsfälle"
msgstr "Pole"

#: ardupilot_methodic_configurator/vehicle_components.py:41
msgid "Product"
msgstr "Benutzerhandbuch."
msgstr "Produkt"

#: ardupilot_methodic_configurator/vehicle_components.py:42
msgid "Program version"
msgstr "Ich verstehe das"
msgstr "Programmversion"

#: ardupilot_methodic_configurator/vehicle_components.py:43
Expand Down
Loading
Loading