lyriarest

package module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2026 License: MIT Imports: 11 Imported by: 0

README

🎧 Lyria REST

Status Language Go Version Go Reference

🚀 概要 (About) - Lyria を interactions で直接呼び、WAV を要求します。保存も作詞もしません

Lyria REST は、音楽生成モデル Lyria を Gemini API の interactions エンドポイントで 直接呼び、音声を WAV で要求するための Go ライブラリです。返すのは音声バイト列と、モデルが 返すテキストだけで、保存先は決めません。歌詞や楽曲レシピを作る工程も持ちません。

[!WARNING] 現在このライブラリは動きません。 Lyria が WAV の要求を受け付けないためで、こちらの 実装の問題ではありません。呼び出すと必ず HTTP 400 になります。 経緯と、再開できるようになったかの判定方法は凍結の理由にあります。

音楽生成の既定の入口は genai-kitlyria です。

シグネチャ・フィールド・エラーの一覧は pkg.go.dev にあります。ここに書くのは、 godoc を読んでも気付けないことだけです。


🧊 凍結の理由 (Blocked upstream)

WAV は SDK の制約ではなく、モデルが出力していません。 2026-09-07 に実機で確認しました。

interactionsresponse_format には出力形式の口があり、API のバリデーションは audio/wav を正しい値として受け付けます(公式 Python SDK google-genaiAudioResponseFormat.mime_type に列挙されています)。ところが、その先のモデルが弾きます。

lyria-3.5             → Audio MIME type AUDIO_WAV is not supported for models/lyria-3.5
lyria-3-pro-preview   → 同上
lyria-3-clip-preview  → 同上

audio/l16audio/ogg_opus も同じで、既定であるはずの audio/mp3 を明示しても拒否されます。 形式指定そのものを受け付けず、常に既定の MP3(mime_type: audio/mpeg)を返す状態です。

試して駄目だった経路は次のとおりです。同じ調査を繰り返さないために残します。

試したこと 結果
generateContent + generationConfig.responseFormat.audio.mimeType: AUDIO_WAV HTTP 400
generateContent + responseMimeType: audio/wav 400(text/plainapplication/json 等のみ許可)
interactions + response_format.mime_type: audio/wav モデルが拒否(3 モデルとも)
同上をリスト形式 [{...}] 同じ
interactions + トップレベル response_mime_type 構造化出力用の別系統(responseFormat must be set when responseMimeType is set
interactions + delivery: "uri" Audio delivery mode is not supported
Accept: audio/wav ヘッダ / ?alt=media 無視され、MP3 が返る

公式ドキュメントとは食い違っています。 Music generation の "Select output format" は「response_format を設定すれば WAV を要求できる」と書いていますが、 続く curl の例は {"type": "audio"} だけで WAV を示すフィールドがなく、そのまま実行すると MP3 が 返ります。ドキュメントが実装より先行しているものと思われます。

API の形そのもの(リクエスト・レスポンスの構造、Python SDK の型定義)は docs/interactions-api.md にまとめてあります。

再開できるか調べる方法

この 1 コマンドで判定できます。WAV が返るようになったら、このライブラリは何も変えずに動きます

curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"lyria-3.5","input":"piano","response_format":{"type":"audio","mime_type":"audio/wav"}}'

✨ 提供機能 (Features)

  • genai-kit の gemini.Generator をそのまま満たします: これが設計の中心です。genai-kit の lyria.Newlyria.WithAudioGenerator(client) で渡すと、音声生成だけがこちらを通り、 作詞・作曲・Track・呼び出しガード・プロンプト構築は genai-kit のものがそのまま動きます。 SDK に戻すときはオプションを外すだけです。genai-kit を import するのは型を共有するためで、 SDK の呼び出しは含みません。
  • WAV 前提です: 出力フォーマットを選ばせる口は置きません。フォーマットを選びたいのではなく WAV が欲しいからこのライブラリがあるので、選択肢を持つと存在理由がぼやけます。MP3 で よいなら genai-kit を使うほうが得です(リトライ・認証・型の面倒を SDK が見ます)。
  • バックエンドは Gemini API だけです: interactions は Gemini API のエンドポイントで、 Lyria もそちらにしか無いためです。v1lyria-3.5 を知らず、v1alpha は廃止済みなので、 v1beta が唯一の経路です。
  • 失敗の分類は genai-kit のセンチネルで判定できます: 空のレスポンスは gemini.ErrEmptyResponseerrors.Is が通ります。interaction が completed 以外で 返った場合も同じセンチネルに加えて ErrIncomplete でも判定できます。API が 2xx 以外を 返した場合は HTTPErrorStatusCode・API のエラーコード Code・メッセージ付き、 errors.Is(err, ErrHTTP))です。
  • リトライを持ちません: SDK 内蔵のリトライは通りません。再試行の判断は呼び出し側で 行ってください。発射間隔・上限時間・重複排除が要る場合は、genai-kit の callguard で包み、 テキスト生成と 1 つのガードを共有する形でワークフロー層に置いてください。
  • 保存も後処理もしません: 返すのはバイト列です。GCS への書き出しは go-remote-io、WAV の無劣化結合や読みの正規化は audio が持ちます。

🚦 使い方 (Usage)

go get github.com/shouni/lyria-rest

genai-kit の gemini.Generator と同じ呼び方です。

client, err := lyriarest.New(lyriarest.Config{APIKey: os.Getenv("GEMINI_API_KEY")})
if err != nil {
	log.Fatal(err)
}

resp, err := client.Generate(ctx, "lyria-3.5",
	"Title: 'Light Me Up'. Euphoric festival EDM pop, 126 BPM, F minor.",
	nil, gemini.GenerateOptions{})
if err != nil {
	log.Fatal(err) // 現在はここで HTTP 400(凍結の理由を参照)
}

// resp.Audios[0] が音声、resp.Text にはモデルが返す譜面テキストが入ります。

genai-kit のワークフローに差し込むなら、lyria.New のオプションに渡します。 作詞・作曲は従来どおり SDK のクライアントが担い、音声だけがこちらを通ります。

workflow, err := lyria.New(sdkClient, textPrompts, audioPrompts,
	lyria.WithGeminiModel("gemini-3.8-flash"),
	lyria.WithLyriaModel("lyria-3.5"),
	lyria.WithAudioGenerator(client), // ← SDK が WAV に対応したら、この 1 行を外す
)

🤝 依存関係 (Dependencies)

  • genai-kit - gemini.Generator / Attachment / GenerateOptions / Response の型を共有するため。SDK の呼び出しは含みません

📜 ライセンス (License)

MIT License. 詳細は LICENSE を参照してください。

Documentation

Overview

Package lyriarest は、Gemini API の Lyria を interactions エンドポイントで直接呼び、 WAV を要求します。

genai SDK には音声の出力フォーマットを指定する口が無く、既定の MP3 しか受け取れません。 REST の interactions には response_format.mime_type があるため、その 1 点のために SDK を 迂回するのがこのパッケージです。

2026-09-07 時点で、Lyria のどのモデルもこの指定を受け付けません。API のバリデーションは audio/wav を通し、その先のモデルが弾きます。したがって現在このパッケージは常に HTTP 400 を返します。凍結の経緯と再開の判定方法は README にあります。

Client は genai-kit の gemini.Generator を満たします。genai-kit の lyria.New には lyria.WithAudioGenerator でこの Client を渡せるので、Workflow・Track・呼び出しガード・ プロンプト構築はすべて genai-kit のものをそのまま使い回せます。戻すときはオプションを 外すだけです。genai-kit を import するのは型(Generator / Attachment / GenerateOptions / Response)を共有するためで、SDK の呼び出しは含みません。

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrAPIKeyRequired は、Config.APIKey が空の場合に返されます。
	ErrAPIKeyRequired = errors.New("lyriarest: APIKey is required")
	// ErrEmptyModelName は、モデル名が空の場合に返されます。
	ErrEmptyModelName = errors.New("lyriarest: model name is empty")
	// ErrEmptyInput は、プロンプトも添付も無く送るものが無い場合に返されます。
	ErrEmptyInput = errors.New("lyriarest: input is empty")
	// ErrInvalidAttachment は、添付の指定が不正な場合に返されます。
	// Data と URI の併用、および Data に MIME type が無い場合が該当します。
	ErrInvalidAttachment = errors.New("lyriarest: invalid attachment")
	// ErrUnsupportedAttachment は、扱えない種類の添付が渡された場合に返されます。
	//
	// interactions の入力ブロックは種類ごとに型が分かれています。このパッケージは
	// Lyria の用途で確認できた image だけを送ります。
	ErrUnsupportedAttachment = errors.New("lyriarest: only image attachments are supported")
	// ErrInvalidSeed は、Seed が int32 の範囲外の場合に返されます。
	ErrInvalidSeed = errors.New("lyriarest: seed must fit in int32")
	// ErrHTTP は、API が 2xx 以外を返したことを示します。詳細は HTTPError にあります。
	ErrHTTP = errors.New("lyriarest: request failed")
	// ErrResponseTooLarge は、レスポンス本文がサイズ上限を超えた場合に返されます。
	ErrResponseTooLarge = errors.New("lyriarest: response body exceeds the size limit")
	// ErrIncomplete は、interaction が completed 以外の状態で返された場合に返されます。
	//
	// 同じエラーは gemini.ErrEmptyResponse でも判定できます(ResponseError を参照)。
	// こちらは「空だった」ではなく「終わらなかった」ことを区別したい呼び出し側向けです。
	ErrIncomplete = errors.New("lyriarest: interaction did not complete")
)

センチネルの文言は英語 + "lyriarest: " プレフィックスで統一しています。深いラップの 中に埋まってもどのパッケージ由来か判別できるようにするためで、人間向けの文脈は ラップする側(fmt.Errorf の %w)が日本語で補います。

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client は Lyria の interactions クライアントです。

func New

func New(cfg Config) (*Client, error)

New は提供された設定に基づいてクライアントを作成します。

func (*Client) Generate

func (c *Client) Generate(ctx context.Context, model string, prompt string, attachments []gemini.Attachment, opts gemini.GenerateOptions) (*gemini.Response, error)

Generate は、プロンプトと添付から生成を実行します。genai-kit の gemini.Generator と同じ契約です。

リトライは持ちません。SDK 内蔵のリトライは通らないため、必要なら呼び出し側で genai-kit の callguard などで包んでください。打ち切りは呼び出し側の context に従います。

type Config

type Config struct {
	// APIKey は Gemini API のキーです。必須。
	APIKey string

	// HTTPClient は REST 呼び出しに使う HTTP クライアントです。nil なら http.Client の
	// ゼロ値(タイムアウト無し)を使い、打ち切りは呼び出し側の context にのみ従います。
	//
	// 認証はヘッダで行うため、Transport を差し替えても認証は失われません。
	HTTPClient *http.Client

	// Endpoint はベース URL の上書きです。空なら公式ホストを使います。
	// テストや私設プロキシ向けで、通常は設定しません。
	Endpoint string
}

Config は初期化用の設定です。

Vertex AI の設定はありません。interactions は Gemini API のエンドポイントで、Lyria も そちらにしか無いためです(Vertex AI に最新の Lyria が来た日には、ここへ ProjectID / LocationID が増えます)。

type HTTPError

type HTTPError struct {
	StatusCode int
	// Code は API が返したエラーコードです("invalid_request"、"resource_exhausted" など)。
	// interactions は文字列で返しますが、ゲートウェイ由来のエラー(認証失敗など)は
	// 数値で返すため、その場合は数値を文字列にしたものが入ります。取り出せなければ空です。
	Code string
	// Message は API が返したエラーメッセージです。取り出せなければ本文の先頭が入ります。
	Message string
}

HTTPError は、API が 2xx 以外のステータスを返した場合のエラーです。 errors.Is(err, ErrHTTP) で分類でき、StatusCode と Code で再試行の可否を判断できます。

WAV が拒否される現在の状態もここに現れます(HTTP 400、Code "invalid_request"、 "Audio MIME type AUDIO_WAV is not supported for models/lyria-3.5")。

func (*HTTPError) Error

func (e *HTTPError) Error() string

func (*HTTPError) Unwrap

func (e *HTTPError) Unwrap() error

Unwrap は分類用センチネル ErrHTTP を返します。

type ResponseError

type ResponseError struct {
	// Reason は分類用のセンチネルです。
	Reason error
	// Status は interaction の状態です("completed" 以外のときに入ります)。
	// 設定されている場合は errors.Is(err, ErrIncomplete) も真になります。
	Status string
	// Message は人間向けの説明です。
	Message string
}

ResponseError は、API との通信は成功したがレスポンスが利用できない場合のエラーです。

Reason には genai-kit の gemini.ErrEmptyResponse を入れます。genai-kit の経路に戻した ときも呼び出し側の errors.Is が同じ分岐を通るように、センチネルを独自に持たず借りています。 genai-kit の gemini.APIResponseError とは別の型ですが、interactions 固有の Status を 持たせるためにこちらで定義しています。

func (*ResponseError) Error

func (e *ResponseError) Error() string

func (*ResponseError) Unwrap

func (e *ResponseError) Unwrap() []error

Unwrap は分類用センチネルを返し、errors.Is による判定を可能にします。

Status が入っている(interaction が完了しなかった)場合は ErrIncomplete も含めるので、 呼び出し側は gemini.ErrEmptyResponse と ErrIncomplete のどちらでも分岐できます。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL