1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
ErrorDetail に `code`(機械処理用のエラーコード)を追加して、エラー種類ごとにメッセージテンプレートとhintを規定します。大きく **構文エラー** と **システムエラー** の2種に分けます。
---
## ErrorDetail 構造(改訂)
```
{
code: string, # エラーコード(機械処理用、LLMがパターン認識可能)
line: int, # 行番号(1始まり)
column: int, # 列番号(1始まり)
message: string, # エラーメッセージ(プレースホルダ展開済み)
severity: "error" | "warning",
hint: string, # LLM向けの修正ヒント
context: string # 該当箇所の周辺テキスト(任意)
}
```
> `code` を追加しました。LLMは `code` を見てエラーパターンを分類し、`hint` に従って修正できます。`context` は該当行のテキスト前後を切り出したもので、LLMが位置を特定しやすくなります。
> **注意**: `line` と `column` は **1始まり** です(最初の行・最初の列が1)。システムエラーやAPIレベルエラーなどで位置情報がない場合は `0` を使用します。
---
## エラーコード仕様
### 構文エラー(SYNTAX_*)
LLMがMML記述を修正する対象。`hint` に具体的な修正例を含める。
| code | trigger | message テンプレート | hint | severity |
|---|---|---|---|---|
| `SYNTAX_INVALID_TOKEN` | 解析不能な文字 | `無効な文字 '{char}' が見つかりました。` | `MMLコマンド(c,d,e,f,g,a,b,r,o,l,v,t,q など)を使用してください。` | error |
| `SYNTAX_INVALID_NUMBER` | 数値を期待した位置に数値以外 | `'{command}' の後に数値が必要です。` | `例: {command}{example} のように数値を指定してください。` | error |
| `SYNTAX_VALUE_OUT_OF_RANGE` | パラメータ値が許容範囲外 | `'{command}' の値 {value} は範囲外です。有効範囲: {min}〜{max}。` | `例: {command}{valid_example} のように指定してください。` | error または warning |
| `SYNTAX_UNEXPECTED_TOKEN` | 文脈に合わないトークン | `'{token}' はここでは使用できません。` | `期待される要素: {expected}。直前のコマンドを確認してください。` | error |
| `SYNTAX_UNTERMINATED_REPEAT` | `[` に対応する `]` がない | `リピート '[' に対応する ']' が見つかりません。` | `] を追加してリピートを閉じてください。回数指定(例: ]2)も可能です。` | error |
| `SYNTAX_UNMATCHED_REPEAT_END` | `]` に対応する `[` がない | `']' に対応する '[' が見つかりません。` | `直前の [ を確認するか、余分な ] を削除してください。` | error |
| `SYNTAX_UNTERMINATED_TIE` | `&` の後に音符がない | `タイ '&' の後に音符が見つかりません。` | `& の後に音符(例: {note_example})を続けてください。音長のみ(例: &16)も可能です(pyxelモード)。` | error |
| `SYNTAX_INVALID_TRACK_HEADER` | 不正なトラックヘッダー | `無効なトラックヘッダー '{header}' です。` | ppmck: `A, B, T, N, L のいずれかを使用してください。` / pyxel: `0:, 1:, 2:, 3: のいずれかを使用してください。` | error |
| `SYNTAX_DUPLICATE_TRACK` | 同じトラックが複数回定義 | `トラック '{track}' が複数回定義されています。` | `各トラックは1回のみ定義できます。重複定義を削除してください。` | error |
| `SYNTAX_EMPTY_TRACK` | トラックに音符・休符がない | `トラック '{track}' に音符または休符がありません。` | `少なくとも1つの音符または休符を記述してください。` | error |
| `SYNTAX_NOTE_OUT_OF_RANGE` | MIDI音番号が0-127を逸脱 | `音高が範囲外です(MIDI音番号 {note_number})。オクターブ {octave} の音符 '{note}' は生成できません。` | `オクターブを調整してください。有効範囲: o{min_oct}〜o{max_oct}。` | warning(クランプ) |
| `SYNTAX_CHANNEL_MISMATCH` | チャンネルに不適切なコマンド | `チャンネル '{channel}' で '{command}' は使用できません。` | `{channel_description}。コマンドを削除するか、適切なチャンネルに移動してください。` | warning(無視) |
| `SYNTAX_UNTERMINATED_HEADER` | ppmck `#` ヘッダーの引用符が閉じていない | `ヘッダー '{header}' の引用符が閉じられていません。` | `二重引用符 " で値を閉じてください。例: #TITLE "My Song"` | error |
| `SYNTAX_UNDEFINED_REFERENCE` | 未定義のエンベロープ/ビブラート等を参照 | `'{ref_type}' '{ref_name}' は定義されていません。` | `使用前に定義してください。例: {definition_example}` | error |
#### チャンネル不適合の具体例(SYNTAX_CHANNEL_MISMATCH)
| 状況 | message | hint |
|---|---|---|
| Triangle + `q2` (ppmck) | `チャンネル 'Triangle' で 'q' は使用できません。` | `Triangleチャンネルはデューティ比を持ちません。q コマンドを削除してください。` |
| Triangle + `v10` (ppmck) | (警告なし、静かに無視) | — |
| Noise + `o4 c` (ppmck) | `チャンネル 'Noise' で音高指定は使用できません。` | `Noiseチャンネルでは音高ではなく音長と音量のみ指定してください。` |
| トラック2(Triangle) + `@1` (pyxel) | `チャンネル 'Triangle' で '@1' (Square) は使用できません。` | `トラック番号がチャンネルを決定します。@ コマンドを削除するか、Pulseチャンネル(0: または 1:)に移動してください。` |
#### 値範囲外の具体例(SYNTAX_VALUE_OUT_OF_RANGE)
| 状況 | message | hint | severity |
|---|---|---|---|
| `o9` (ppmck/pyxel) | `'o' の値 9 は範囲外です。有効範囲: 0〜7。` | `例: o4 のように指定してください。` | error |
| `v20` (ppmck) | `'v' の値 20 は範囲外です。有効範囲: 0〜15。` | `例: v15 のように指定してください。` | error |
| `V200` (pyxel) | `'V' の値 200 は範囲外です。有効範囲: 0〜127。` | `例: V100 のように指定してください。` | error |
| `l0` (両モード) | `'l' の値 0 は範囲外です。有効範囲: 1〜192。` | `例: l8 のように指定してください。` | error |
| `t0` (両モード) | `'t' の値 0 は範囲外です。有効範囲: 1以上。` | `例: t150 のように指定してください。` | error |
---
### システムエラー(SYSTEM_*)
LLMの修正対象外。内部処理の失敗。`hint` は空または「再試行してください」程度。
| code | trigger | message テンプレート | hint | severity |
|---|---|---|---|---|
| `SYSTEM_SYNTHESIS_FAILED` | 音声合成中のnumpy演算エラー等 | `音声合成中にエラーが発生しました: {detail}` | `MMLの内容を確認の上、再度お試しください。問題が続く場合は、短いMMLから試してください。` | error |
| `SYSTEM_WAV_WRITE_FAILED` | WAVファイル出力の失敗 | `WAVファイルの出力に失敗しました: {detail}` | `しばらく待ってから再度お試しください。` | error |
| `SYSTEM_INTERNAL_ERROR` | 予期しない例外 | `内部エラーが発生しました: {detail}` | `MMLの内容を確認の上、再度お試しください。` | error |
> システムエラーは `compose` actionでのみ発生しうる。`validate` / `template` actionでは構文エラー以外は返らない設計。
---
### APIレベルエラー(VALIDATION_*)
MML構文ではなく、APIパラメータのバリデーションエラー。`line` / `column` は `0` となります。
| code | trigger | message テンプレート | hint | severity |
|---|---|---|---|---|
| `VALIDATION_MISSING_PARAMETER` | compose/validateで必須パラメータ(mml, mode)が欠落 | `mml と mode は compose/validate の必須パラメータです。` | `mml に MML 文字列、mode に 'ppmck' または 'pyxel' を指定してください。` | error |
| `VALIDATION_INVALID_MODE` | 未知のmodeが指定された | `未知のモード '{mode}' です。` | `mode は 'ppmck' または 'pyxel' を指定してください。` | error |
| `VALIDATION_INVALID_ACTION` | 未知のactionが指定された | `未知の action '{action}' です。` | `action は 'compose', 'validate', 'template' のいずれかを指定してください。` | error |
---
### エラーレスポンスの実例
#### 構文エラーの例(LLMが修正可能)
```json
{
"code": "SYNTAX_UNTERMINATED_REPEAT",
"line": 5,
"column": 18,
"message": "リピート '[' に対応する ']' が見つかりません。",
"severity": "error",
"hint": "] を追加してリピートを閉じてください。回数指定(例: ]2)も可能です。",
"context": " [ c d e f | g a b > c"
}
```
LLMはこれを見て、「5行目の `[` に `]` を追加すればいい」と判断できる。
#### 値範囲外の例
```json
{
"code": "SYNTAX_VALUE_OUT_OF_RANGE",
"line": 2,
"column": 7,
"message": "'v' の値 20 は範囲外です。有効範囲: 0〜15。",
"severity": "error",
"hint": "例: v15 のように指定してください。",
"context": "A t150 l8 o4 v20 q2"
}
```
#### システムエラーの例
```json
{
"code": "SYSTEM_SYNTHESIS_FAILED",
"line": 0,
"column": 0,
"message": "音声合成中にエラーが発生しました: frequency calculation overflow at note_number 135",
"severity": "error",
"hint": "MMLの内容を確認の上、再度お試しください。問題が続く場合は、短いMMLから試してください。",
"context": ""
}
```
---
### エラー発生時のcompose_mml戻り値(改訂)
```
compose action で ERROR がある場合:
{
success: false,
wav_path: null, # WAVは生成しない
duration_sec: 0,
note_sequence: null, # 解析途中で停止した場合はnull
validation: {
errors: [ErrorDetail, ...], # 構文エラー・システムエラー
warnings: [ErrorDetail, ...] # warningはerrorsとは別に格納
}
}
```
> warnings も ErrorDetail 構造で返す(severity = "warning")。LLMは warnings を見て「修正しなくても動くが、改善できる」ことを把握できる。
---
これで、エラーまわりの仕様を規定しました。構文エラーは14種類、システムエラーは3種類、APIレベルエラーは3種類。LLMが `code` を見てパターン認識し、`hint` に従って修正できる構造になっています。
|