From 6f2c8059243d7971de0a5a8885b2831dff0e04d9 Mon Sep 17 00:00:00 2001 From: SSharma-10 Date: Thu, 15 Oct 2026 21:03:55 +0530 Subject: [PATCH] dd speech and video Inference APIs with multi-language examples --- specification/DigitalOcean-public.v2.yaml | 17 ++++++ ...agent_inference_create_chat_completion.yml | 1 + .../examples/curl/inference_create_speech.yml | 13 ++++ .../examples/curl/inference_create_video.yml | 11 ++++ .../examples/curl/inference_get_video.yml | 4 ++ .../curl/inference_get_video_content.yml | 5 ++ .../examples/dots/inference_create_speech.yml | 19 ++++++ .../examples/dots/inference_create_video.yml | 16 +++++ .../examples/dots/inference_get_video.yml | 10 ++++ .../dots/inference_get_video_content.yml | 11 ++++ .../agentInference_create_chat_completion.yml | 37 ++++++++++++ .../examples/go/inference_async_invoke.yml | 30 ++++++++++ .../examples/go/inference_cancel_batch.yml | 27 +++++++++ .../examples/go/inference_create_batch.yml | 37 ++++++++++++ .../go/inference_create_batch_file.yml | 26 ++++++++ .../go/inference_create_chat_completion.yml | 30 ++++++++++ .../inference_create_chat_completion_kb.yml | 37 ++++++++++++ .../inference_create_chat_completion_mcp.yml | 42 +++++++++++++ .../inference_create_chat_completion_vlm.yml | 41 +++++++++++++ .../go/inference_create_embeddings.yml | 39 ++++++++++++ .../examples/go/inference_create_image.yml | 29 +++++++++ .../examples/go/inference_create_messages.yml | 39 ++++++++++++ .../examples/go/inference_create_response.yml | 28 +++++++++ ...erence_create_response_model_synthesis.yml | 33 +++++++++++ .../inference_create_response_tool_search.yml | 38 ++++++++++++ .../inference_create_response_web_fetch.yml | 31 ++++++++++ .../inference_create_response_web_search.yml | 31 ++++++++++ .../examples/go/inference_create_speech.yml | 36 +++++++++++ .../examples/go/inference_create_video.yml | 28 +++++++++ .../examples/go/inference_get_batch.yml | 28 +++++++++ .../go/inference_get_batch_results.yml | 53 +++++++++++++++++ .../examples/go/inference_get_video.yml | 23 ++++++++ .../go/inference_get_video_content.yml | 25 ++++++++ .../examples/go/inference_list_batches.yml | 31 ++++++++++ .../examples/go/inference_list_models.yml | 25 ++++++++ .../go/inference_upload_batch_file.yml | 38 ++++++++++++ .../python/inference_create_speech.yml | 19 ++++++ .../python/inference_create_video.yml | 15 +++++ .../examples/python/inference_get_video.yml | 9 +++ .../python/inference_get_video_content.yml | 11 ++++ .../inference/inference_async_invoke.yml | 1 + .../inference/inference_cancel_batch.yml | 1 + .../inference/inference_create_batch.yml | 1 + .../inference/inference_create_batch_file.yml | 1 + .../inference_create_chat_completion.yml | 4 ++ .../inference/inference_create_embeddings.yml | 1 + .../inference/inference_create_image.yml | 1 + .../inference/inference_create_messages.yml | 1 + .../inference/inference_create_response.yml | 5 ++ .../inference/inference_create_speech.yml | 59 +++++++++++++++++++ .../inference/inference_create_video.yml | 48 +++++++++++++++ .../inference/inference_get_batch.yml | 1 + .../inference/inference_get_batch_results.yml | 1 + .../inference/inference_get_video.yml | 50 ++++++++++++++++ .../inference/inference_get_video_content.yml | 50 ++++++++++++++++ .../inference/inference_list_batches.yml | 1 + .../inference/inference_list_models.yml | 1 + .../inference/inference_upload_batch_file.yml | 1 + .../models/create_speech_request.yml | 29 +++++++++ .../inference/models/create_video_request.yml | 24 ++++++++ .../inference/models/speech_audio_item.yml | 9 +++ .../inference/models/speech_response.yml | 17 ++++++ .../inference/models/video_generation.yml | 40 +++++++++++++ .../models/video_generation_output.yml | 8 +++ 64 files changed, 1378 insertions(+) create mode 100644 specification/resources/inference/examples/curl/inference_create_speech.yml create mode 100644 specification/resources/inference/examples/curl/inference_create_video.yml create mode 100644 specification/resources/inference/examples/curl/inference_get_video.yml create mode 100644 specification/resources/inference/examples/curl/inference_get_video_content.yml create mode 100644 specification/resources/inference/examples/dots/inference_create_speech.yml create mode 100644 specification/resources/inference/examples/dots/inference_create_video.yml create mode 100644 specification/resources/inference/examples/dots/inference_get_video.yml create mode 100644 specification/resources/inference/examples/dots/inference_get_video_content.yml create mode 100644 specification/resources/inference/examples/go/agentInference_create_chat_completion.yml create mode 100644 specification/resources/inference/examples/go/inference_async_invoke.yml create mode 100644 specification/resources/inference/examples/go/inference_cancel_batch.yml create mode 100644 specification/resources/inference/examples/go/inference_create_batch.yml create mode 100644 specification/resources/inference/examples/go/inference_create_batch_file.yml create mode 100644 specification/resources/inference/examples/go/inference_create_chat_completion.yml create mode 100644 specification/resources/inference/examples/go/inference_create_chat_completion_kb.yml create mode 100644 specification/resources/inference/examples/go/inference_create_chat_completion_mcp.yml create mode 100644 specification/resources/inference/examples/go/inference_create_chat_completion_vlm.yml create mode 100644 specification/resources/inference/examples/go/inference_create_embeddings.yml create mode 100644 specification/resources/inference/examples/go/inference_create_image.yml create mode 100644 specification/resources/inference/examples/go/inference_create_messages.yml create mode 100644 specification/resources/inference/examples/go/inference_create_response.yml create mode 100644 specification/resources/inference/examples/go/inference_create_response_model_synthesis.yml create mode 100644 specification/resources/inference/examples/go/inference_create_response_tool_search.yml create mode 100644 specification/resources/inference/examples/go/inference_create_response_web_fetch.yml create mode 100644 specification/resources/inference/examples/go/inference_create_response_web_search.yml create mode 100644 specification/resources/inference/examples/go/inference_create_speech.yml create mode 100644 specification/resources/inference/examples/go/inference_create_video.yml create mode 100644 specification/resources/inference/examples/go/inference_get_batch.yml create mode 100644 specification/resources/inference/examples/go/inference_get_batch_results.yml create mode 100644 specification/resources/inference/examples/go/inference_get_video.yml create mode 100644 specification/resources/inference/examples/go/inference_get_video_content.yml create mode 100644 specification/resources/inference/examples/go/inference_list_batches.yml create mode 100644 specification/resources/inference/examples/go/inference_list_models.yml create mode 100644 specification/resources/inference/examples/go/inference_upload_batch_file.yml create mode 100644 specification/resources/inference/examples/python/inference_create_speech.yml create mode 100644 specification/resources/inference/examples/python/inference_create_video.yml create mode 100644 specification/resources/inference/examples/python/inference_get_video.yml create mode 100644 specification/resources/inference/examples/python/inference_get_video_content.yml create mode 100644 specification/resources/inference/inference_create_speech.yml create mode 100644 specification/resources/inference/inference_create_video.yml create mode 100644 specification/resources/inference/inference_get_video.yml create mode 100644 specification/resources/inference/inference_get_video_content.yml create mode 100644 specification/resources/inference/models/create_speech_request.yml create mode 100644 specification/resources/inference/models/create_video_request.yml create mode 100644 specification/resources/inference/models/speech_audio_item.yml create mode 100644 specification/resources/inference/models/speech_response.yml create mode 100644 specification/resources/inference/models/video_generation.yml create mode 100644 specification/resources/inference/models/video_generation_output.yml diff --git a/specification/DigitalOcean-public.v2.yaml b/specification/DigitalOcean-public.v2.yaml index a14a06c72..3028f3ebd 100644 --- a/specification/DigitalOcean-public.v2.yaml +++ b/specification/DigitalOcean-public.v2.yaml @@ -3392,6 +3392,23 @@ paths: post: $ref: 'resources/inference/inference_async_invoke.yml' + + /v1/audio/speech: + post: + $ref: 'resources/inference/inference_create_speech.yml' + + /v1/videos: + post: + $ref: 'resources/inference/inference_create_video.yml' + + /v1/videos/{video_id}: + get: + $ref: 'resources/inference/inference_get_video.yml' + + /v1/videos/{video_id}/content: + get: + $ref: 'resources/inference/inference_get_video_content.yml' + /v1/batches/files: post: $ref: 'resources/inference/inference_create_batch_file.yml' diff --git a/specification/resources/inference/agent_inference_create_chat_completion.yml b/specification/resources/inference/agent_inference_create_chat_completion.yml index 5b4ffc23e..00d242290 100644 --- a/specification/resources/inference/agent_inference_create_chat_completion.yml +++ b/specification/resources/inference/agent_inference_create_chat_completion.yml @@ -55,6 +55,7 @@ responses: x-codeSamples: - $ref: 'examples/curl/agentInference_create_chat_completion.yml' - $ref: 'examples/python/agentInference_create_chat_completion.yml' + - $ref: 'examples/go/agentInference_create_chat_completion.yml' - $ref: 'examples/dots/agentInference_create_chat_completion.yml' security: - inference_bearer_auth: [] diff --git a/specification/resources/inference/examples/curl/inference_create_speech.yml b/specification/resources/inference/examples/curl/inference_create_speech.yml new file mode 100644 index 000000000..3ab78b694 --- /dev/null +++ b/specification/resources/inference/examples/curl/inference_create_speech.yml @@ -0,0 +1,13 @@ +lang: cURL +source: |- + curl -sS https://inference.do-ai.run/v1/audio/speech \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "model": "qwen3-tts-voicedesign", + "input": "Hello, world!", + "voice": "alloy", + "response_format": "mp3", + "instructions": "Speak naturally." + }' \ + --output output.mp3 diff --git a/specification/resources/inference/examples/curl/inference_create_video.yml b/specification/resources/inference/examples/curl/inference_create_video.yml new file mode 100644 index 000000000..d3b1913ba --- /dev/null +++ b/specification/resources/inference/examples/curl/inference_create_video.yml @@ -0,0 +1,11 @@ +lang: cURL +source: |- + curl -X POST https://inference.do-ai.run/v1/videos \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "model": "wan2-2-t2v-a14b", + "prompt": "Two anthropomorphic cats in boxing gear fight intensely on a spotlighted stage", + "size": "1280x720", + "fps": 16 + }' diff --git a/specification/resources/inference/examples/curl/inference_get_video.yml b/specification/resources/inference/examples/curl/inference_get_video.yml new file mode 100644 index 000000000..e77bcda2e --- /dev/null +++ b/specification/resources/inference/examples/curl/inference_get_video.yml @@ -0,0 +1,4 @@ +lang: cURL +source: |- + curl https://inference.do-ai.run/v1/videos/$VIDEO_ID \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" diff --git a/specification/resources/inference/examples/curl/inference_get_video_content.yml b/specification/resources/inference/examples/curl/inference_get_video_content.yml new file mode 100644 index 000000000..5bfd35e63 --- /dev/null +++ b/specification/resources/inference/examples/curl/inference_get_video_content.yml @@ -0,0 +1,5 @@ +lang: cURL +source: |- + curl https://inference.do-ai.run/v1/videos/$VIDEO_ID/content \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + --output output.mp4 diff --git a/specification/resources/inference/examples/dots/inference_create_speech.yml b/specification/resources/inference/examples/dots/inference_create_speech.yml new file mode 100644 index 000000000..6364f2dc9 --- /dev/null +++ b/specification/resources/inference/examples/dots/inference_create_speech.yml @@ -0,0 +1,19 @@ +lang: JavaScript +source: |- + import { writeFileSync } from "fs"; + import { InferenceClient } from "@digitalocean/dots"; + + const client = new InferenceClient({ + apiKey: process.env.DIGITALOCEAN_TOKEN, + }); + + const response = await client.audio.speech.create({ + model: "qwen3-tts-voicedesign", + input: "Hello, world!", + voice: "alloy", + response_format: "mp3", + instructions: "Speak naturally.", + }); + + const audioBytes = Buffer.from(response.data[0].b64_json, "base64"); + writeFileSync("output.mp3", audioBytes); diff --git a/specification/resources/inference/examples/dots/inference_create_video.yml b/specification/resources/inference/examples/dots/inference_create_video.yml new file mode 100644 index 000000000..4212f19c4 --- /dev/null +++ b/specification/resources/inference/examples/dots/inference_create_video.yml @@ -0,0 +1,16 @@ +lang: JavaScript +source: |- + import { InferenceClient } from "@digitalocean/dots"; + + const client = new InferenceClient({ + apiKey: process.env.DIGITALOCEAN_TOKEN, + }); + + const job = await client.video.generations.create({ + model: "wan2-2-t2v-a14b", + prompt: "Two anthropomorphic cats in boxing gear fight intensely on a spotlighted stage", + size: "1280x720", + fps: 16, + }); + + console.log(job.id, job.status); diff --git a/specification/resources/inference/examples/dots/inference_get_video.yml b/specification/resources/inference/examples/dots/inference_get_video.yml new file mode 100644 index 000000000..322b07ba9 --- /dev/null +++ b/specification/resources/inference/examples/dots/inference_get_video.yml @@ -0,0 +1,10 @@ +lang: JavaScript +source: |- + import { InferenceClient } from "@digitalocean/dots"; + + const client = new InferenceClient({ + apiKey: process.env.DIGITALOCEAN_TOKEN, + }); + + const job = await client.video.generations.retrieve(process.env.VIDEO_ID); + console.log(job.id, job.status); diff --git a/specification/resources/inference/examples/dots/inference_get_video_content.yml b/specification/resources/inference/examples/dots/inference_get_video_content.yml new file mode 100644 index 000000000..a2e4e31db --- /dev/null +++ b/specification/resources/inference/examples/dots/inference_get_video_content.yml @@ -0,0 +1,11 @@ +lang: JavaScript +source: |- + import { writeFileSync } from "fs"; + import { InferenceClient } from "@digitalocean/dots"; + + const client = new InferenceClient({ + apiKey: process.env.DIGITALOCEAN_TOKEN, + }); + + const content = await client.video.generations.content(process.env.VIDEO_ID); + writeFileSync("output.mp4", Buffer.from(await content.arrayBuffer())); diff --git a/specification/resources/inference/examples/go/agentInference_create_chat_completion.yml b/specification/resources/inference/examples/go/agentInference_create_chat_completion.yml new file mode 100644 index 000000000..d00fba084 --- /dev/null +++ b/specification/resources/inference/examples/go/agentInference_create_chat_completion.yml @@ -0,0 +1,37 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + agent, err := godo.NewAgentInferenceClient( + os.Getenv("AGENT_ENDPOINT"), + os.Getenv("AGENT_ACCESS_KEY"), + ) + if err != nil { + panic(err) + } + + ctx := context.Background() + + completion, _, err := agent.Chat.Completions.New(ctx, &godo.ChatCompletionNewParams{ + Model: "llama3.3-70b-instruct", + Messages: []godo.ChatCompletionMessage{ + godo.UserMessage("What is the capital of Portugal?"), + }, + }) + if err != nil { + panic(err) + } + + if msg := completion.Choices[0].Message.Content; msg != nil { + fmt.Println(msg.Text()) + } + } diff --git a/specification/resources/inference/examples/go/inference_async_invoke.yml b/specification/resources/inference/examples/go/inference_async_invoke.yml new file mode 100644 index 000000000..e502facb4 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_async_invoke.yml @@ -0,0 +1,30 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + // Async invoke uses model_id + a free-form input map. Shape of input + // depends on the model (image, audio, TTS, and so on). + invocation, _, err := client.AsyncInvocations.New(ctx, &godo.AsyncInvocationNewParams{ + ModelID: "fal-ai/flux/schnell", + Input: map[string]interface{}{ + "prompt": "A futuristic city at sunset", + }, + }) + if err != nil { + panic(err) + } + + fmt.Println(invocation.RequestID, invocation.Status) + } diff --git a/specification/resources/inference/examples/go/inference_cancel_batch.yml b/specification/resources/inference/examples/go/inference_cancel_batch.yml new file mode 100644 index 000000000..d649d55e3 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_cancel_batch.yml @@ -0,0 +1,27 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + batch, _, err := client.BatchInference.CancelJob(ctx, os.Getenv("BATCH_ID")) + if err != nil { + panic(err) + } + + fmt.Println("batch_id:", batch.BatchID) + fmt.Println("status: ", batch.Status) + if batch.CancelRequestedAt != nil { + fmt.Println("cancel_requested_at:", *batch.CancelRequestedAt) + } + } diff --git a/specification/resources/inference/examples/go/inference_create_batch.yml b/specification/resources/inference/examples/go/inference_create_batch.yml new file mode 100644 index 000000000..7e5160400 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_batch.yml @@ -0,0 +1,37 @@ +lang: Go +source: |- + package main + + import ( + "context" + "crypto/rand" + "encoding/hex" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + id := make([]byte, 16) + if _, err := rand.Read(id); err != nil { + panic(err) + } + + batch, _, err := client.BatchInference.CreateJob(ctx, &godo.CreateBatchRequest{ + FileID: os.Getenv("BATCH_INPUT_FILE_ID"), + Provider: "openai", + Endpoint: "/v1/chat/completions", + CompletionWindow: "24h", + RequestID: hex.EncodeToString(id), + }) + if err != nil { + panic(err) + } + + fmt.Println("batch_id:", batch.BatchID) + fmt.Println("status: ", batch.Status) + } diff --git a/specification/resources/inference/examples/go/inference_create_batch_file.yml b/specification/resources/inference/examples/go/inference_create_batch_file.yml new file mode 100644 index 000000000..04124a6e1 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_batch_file.yml @@ -0,0 +1,26 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + intent, _, err := client.BatchInference.CreatePresignedUploadURL(ctx, &godo.CreateBatchFileRequest{ + FileName: "batch_requests.jsonl", + }) + if err != nil { + panic(err) + } + + fmt.Println("file_id: ", intent.FileID) + fmt.Println("upload_url:", intent.UploadURL) + } diff --git a/specification/resources/inference/examples/go/inference_create_chat_completion.yml b/specification/resources/inference/examples/go/inference_create_chat_completion.yml new file mode 100644 index 000000000..2d9fc15a3 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_chat_completion.yml @@ -0,0 +1,30 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + completion, _, err := client.Chat.Completions.New(ctx, &godo.ChatCompletionNewParams{ + Model: "llama3.3-70b-instruct", + Messages: []godo.ChatCompletionMessage{ + godo.UserMessage("What is the capital of Portugal?"), + }, + }) + if err != nil { + panic(err) + } + + if msg := completion.Choices[0].Message.Content; msg != nil { + fmt.Println(msg.Text()) + } + } diff --git a/specification/resources/inference/examples/go/inference_create_chat_completion_kb.yml b/specification/resources/inference/examples/go/inference_create_chat_completion_kb.yml new file mode 100644 index 000000000..bf7f3fc30 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_chat_completion_kb.yml @@ -0,0 +1,37 @@ +lang: Go +label: Knowledge base +source: |- + package main + + import ( + "context" + "encoding/json" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + completion, _, err := client.Chat.Completions.New(ctx, &godo.ChatCompletionNewParams{ + Model: "openai-gpt-oss-20b", + Messages: []godo.ChatCompletionMessage{ + godo.UserMessage("What are some features of DigitalOcean Inference?"), + }, + Tools: []godo.ChatCompletionTool{ + godo.ChatKnowledgeBaseRetrievalTool(os.Getenv("KNOWLEDGE_BASE_ID")), + }, + ToolChoice: json.RawMessage(`"auto"`), + MaxTokens: godo.PtrTo(1024), + }) + if err != nil { + panic(err) + } + + if msg := completion.Choices[0].Message.Content; msg != nil { + fmt.Println(msg.Text()) + } + } diff --git a/specification/resources/inference/examples/go/inference_create_chat_completion_mcp.yml b/specification/resources/inference/examples/go/inference_create_chat_completion_mcp.yml new file mode 100644 index 000000000..88d8d4c05 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_chat_completion_mcp.yml @@ -0,0 +1,42 @@ +lang: Go +label: MCP tool +source: |- + package main + + import ( + "context" + "encoding/json" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + completion, _, err := client.Chat.Completions.New(ctx, &godo.ChatCompletionNewParams{ + Model: "openai-gpt-oss-20b", + Messages: []godo.ChatCompletionMessage{ + godo.UserMessage("Fetch my DigitalOcean account information and summarize it in 2 bullets."), + }, + Tools: []godo.ChatCompletionTool{ + godo.ChatMCPTool(godo.MCPToolParams{ + ServerLabel: "digitalocean", + ServerURL: "https://accounts.mcp.digitalocean.com/mcp", + Authorization: "Bearer " + os.Getenv("DIGITALOCEAN_API_TOKEN"), + AllowedTools: []string{"account-get-information"}, + }), + }, + ToolChoice: json.RawMessage(`"required"`), + MaxTokens: godo.PtrTo(512), + }) + if err != nil { + panic(err) + } + + if msg := completion.Choices[0].Message.Content; msg != nil { + fmt.Println(msg.Text()) + } + } diff --git a/specification/resources/inference/examples/go/inference_create_chat_completion_vlm.yml b/specification/resources/inference/examples/go/inference_create_chat_completion_vlm.yml new file mode 100644 index 000000000..58439273b --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_chat_completion_vlm.yml @@ -0,0 +1,41 @@ +lang: Go +label: Vision (VLM) +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + // IMAGE_URL may be an HTTPS URL or a data:image/...;base64,... URI. + imageURL := os.Getenv("IMAGE_URL") + if imageURL == "" { + imageURL = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Online_Bicycles.jpg/640px-Online_Bicycles.jpg" + } + + completion, _, err := client.Chat.Completions.New(ctx, &godo.ChatCompletionNewParams{ + Model: "nemotron-nano-12b-v2-vl", + Messages: []godo.ChatCompletionMessage{ + godo.UserMessageParts( + godo.TextPart("Describe this image."), + godo.ImageURLPart(imageURL), + ), + }, + MaxTokens: godo.PtrTo(512), + }) + if err != nil { + panic(err) + } + + if msg := completion.Choices[0].Message.Content; msg != nil { + fmt.Println(msg.Text()) + } + } diff --git a/specification/resources/inference/examples/go/inference_create_embeddings.yml b/specification/resources/inference/examples/go/inference_create_embeddings.yml new file mode 100644 index 000000000..b956ce947 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_embeddings.yml @@ -0,0 +1,39 @@ +lang: Go +source: |- + package main + + import ( + "context" + "encoding/json" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + resp, _, err := client.Embeddings.New(ctx, &godo.EmbeddingNewParams{ + Model: "qwen3-embedding-0.6b", + Input: []string{"hello world", "goodbye world"}, + EncodingFormat: "float", + User: "user-1234", + }) + if err != nil { + panic(err) + } + + for _, item := range resp.Data { + var vec []float32 + if err := json.Unmarshal(item.Embedding, &vec); err != nil { + panic(err) + } + head := vec + if len(head) > 8 { + head = head[:8] + } + fmt.Println(item.Index, head) + } + } diff --git a/specification/resources/inference/examples/go/inference_create_image.yml b/specification/resources/inference/examples/go/inference_create_image.yml new file mode 100644 index 000000000..be955a0ee --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_image.yml @@ -0,0 +1,29 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + resp, _, err := client.ImageGenerations.Generate(ctx, &godo.ImageGenerateParams{ + Model: "openai-gpt-image-1", + Prompt: "A cute baby sea otter floating on its back in calm blue water", + Size: godo.PtrTo("auto"), + Quality: godo.PtrTo("auto"), + N: 1, + }) + if err != nil { + panic(err) + } + + fmt.Println(resp.Data[0].B64JSON) + } diff --git a/specification/resources/inference/examples/go/inference_create_messages.yml b/specification/resources/inference/examples/go/inference_create_messages.yml new file mode 100644 index 000000000..ad045cc75 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_messages.yml @@ -0,0 +1,39 @@ +lang: Go +source: |- + package main + + import ( + "context" + "encoding/json" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + content, err := json.Marshal("What is the capital of Portugal?") + if err != nil { + panic(err) + } + + msg, _, err := client.Messages.New(ctx, &godo.MessageNewParams{ + Model: "claude-opus-4-6", + MaxTokens: 1024, + Messages: []godo.MessageParam{ + {Role: "user", Content: content}, + }, + }) + if err != nil { + panic(err) + } + + for _, block := range msg.Content { + if block.Type == "text" { + fmt.Println(block.Text) + } + } + } diff --git a/specification/resources/inference/examples/go/inference_create_response.yml b/specification/resources/inference/examples/go/inference_create_response.yml new file mode 100644 index 000000000..daacaabef --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_response.yml @@ -0,0 +1,28 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + resp, _, err := client.Responses.New(ctx, &godo.ResponseNewParams{ + Model: "openai-gpt-oss-20b", + Input: "What is the capital of France?", + MaxOutputTokens: godo.PtrTo(50), + Temperature: godo.PtrTo(0.7), + }) + if err != nil { + panic(err) + } + + fmt.Println(resp.OutputText()) + } diff --git a/specification/resources/inference/examples/go/inference_create_response_model_synthesis.yml b/specification/resources/inference/examples/go/inference_create_response_model_synthesis.yml new file mode 100644 index 000000000..49b92b9db --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_response_model_synthesis.yml @@ -0,0 +1,33 @@ +lang: Go +label: Model synthesis +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + resp, _, err := client.Responses.New(ctx, &godo.ResponseNewParams{ + Model: "openai-gpt-oss-20b", + Input: "Compare approaches for reducing inference latency.", + Tools: []godo.ResponseTool{ + godo.ModelSynthesisTool(godo.ModelSynthesisToolParams{ + Preset: "balanced", + }), + }, + MaxOutputTokens: godo.PtrTo(1024), + }) + if err != nil { + panic(err) + } + + fmt.Println(resp.OutputText()) + } diff --git a/specification/resources/inference/examples/go/inference_create_response_tool_search.yml b/specification/resources/inference/examples/go/inference_create_response_tool_search.yml new file mode 100644 index 000000000..40ac3c803 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_response_tool_search.yml @@ -0,0 +1,38 @@ +lang: Go +label: Tool search +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + resp, _, err := client.Responses.New(ctx, &godo.ResponseNewParams{ + Model: "openai-gpt-5.5", + Input: "Compare the current weather in zip code 94107 and 10001.", + Tools: []godo.ResponseTool{ + godo.FunctionTool("get_weather", "Get weather for a zip code", map[string]interface{}{ + "type": "object", + "properties": map[string]interface{}{ + "zip": map[string]interface{}{"type": "string"}, + }, + "required": []string{"zip"}, + }), + godo.ToolSearchTool(), + }, + MaxOutputTokens: godo.PtrTo(1024), + }) + if err != nil { + panic(err) + } + + fmt.Println(resp.OutputText()) + } diff --git a/specification/resources/inference/examples/go/inference_create_response_web_fetch.yml b/specification/resources/inference/examples/go/inference_create_response_web_fetch.yml new file mode 100644 index 000000000..7d7130537 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_response_web_fetch.yml @@ -0,0 +1,31 @@ +lang: Go +label: Web fetch +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + resp, _, err := client.Responses.New(ctx, &godo.ResponseNewParams{ + Model: "openai-gpt-oss-20b", + Input: "Summarize https://www.digitalocean.com/pricing", + Tools: []godo.ResponseTool{ + godo.WebFetchTool(godo.PtrTo(3)), + }, + MaxOutputTokens: godo.PtrTo(1024), + }) + if err != nil { + panic(err) + } + + fmt.Println(resp.OutputText()) + } diff --git a/specification/resources/inference/examples/go/inference_create_response_web_search.yml b/specification/resources/inference/examples/go/inference_create_response_web_search.yml new file mode 100644 index 000000000..6a3486f8f --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_response_web_search.yml @@ -0,0 +1,31 @@ +lang: Go +label: Web search +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + resp, _, err := client.Responses.New(ctx, &godo.ResponseNewParams{ + Model: "openai-gpt-oss-20b", + Input: "What are the latest pricing changes for DigitalOcean Droplets?", + Tools: []godo.ResponseTool{ + godo.WebSearchTool(godo.PtrTo(3), godo.PtrTo(5)), + }, + MaxOutputTokens: godo.PtrTo(1024), + }) + if err != nil { + panic(err) + } + + fmt.Println(resp.OutputText()) + } diff --git a/specification/resources/inference/examples/go/inference_create_speech.yml b/specification/resources/inference/examples/go/inference_create_speech.yml new file mode 100644 index 000000000..03b2e1b0c --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_speech.yml @@ -0,0 +1,36 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + speech, _, err := client.Audio.Speech.New(ctx, &godo.SpeechNewParams{ + Model: "qwen3-tts-voicedesign", + Input: "Hello, world!", + Voice: "alloy", + ResponseFormat: "mp3", + Instructions: "Speak naturally.", + }) + if err != nil { + panic(err) + } + + audioBytes, err := speech.Bytes() + if err != nil { + panic(err) + } + if err := os.WriteFile("output.mp3", audioBytes, 0644); err != nil { + panic(err) + } + fmt.Println("Wrote output.mp3") + } diff --git a/specification/resources/inference/examples/go/inference_create_video.yml b/specification/resources/inference/examples/go/inference_create_video.yml new file mode 100644 index 000000000..1457a0bf2 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_create_video.yml @@ -0,0 +1,28 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + job, _, err := client.Video.Generations.Create(ctx, &godo.VideoGenerateParams{ + Model: "wan2-2-t2v-a14b", + Prompt: "Two anthropomorphic cats in boxing gear fight intensely on a spotlighted stage", + Size: "1280x720", + FPS: godo.PtrTo(16), + }) + if err != nil { + panic(err) + } + + fmt.Println(job.ID, job.Status) + } diff --git a/specification/resources/inference/examples/go/inference_get_batch.yml b/specification/resources/inference/examples/go/inference_get_batch.yml new file mode 100644 index 000000000..6a492ab88 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_get_batch.yml @@ -0,0 +1,28 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + batch, _, err := client.BatchInference.GetJob(ctx, os.Getenv("BATCH_ID")) + if err != nil { + panic(err) + } + + fmt.Println("batch_id: ", batch.BatchID) + fmt.Println("status: ", batch.Status) + fmt.Println("result_available:", batch.ResultAvailable) + if batch.RequestCounts != nil { + fmt.Printf("request_counts: %+v\n", *batch.RequestCounts) + } + } diff --git a/specification/resources/inference/examples/go/inference_get_batch_results.yml b/specification/resources/inference/examples/go/inference_get_batch_results.yml new file mode 100644 index 000000000..2bd1369a2 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_get_batch_results.yml @@ -0,0 +1,53 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "io" + "net/http" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + batchID := os.Getenv("BATCH_ID") + + batch, _, err := client.BatchInference.GetJob(ctx, batchID) + if err != nil { + panic(err) + } + if !batch.ResultAvailable { + fmt.Println("results not ready yet; poll batch status and retry") + os.Exit(0) + } + + links, _, err := client.BatchInference.GetJobResult(ctx, batchID) + if err != nil { + panic(err) + } + + resp, err := http.Get(links.Download.PresignedURL) + if err != nil { + panic(err) + } + defer resp.Body.Close() + + out, err := os.Create("batch_output.jsonl") + if err != nil { + panic(err) + } + defer out.Close() + + if _, err := io.Copy(out, resp.Body); err != nil { + panic(err) + } + + fmt.Println("wrote: batch_output.jsonl") + fmt.Println("output_file_id:", links.OutputFileID) + } diff --git a/specification/resources/inference/examples/go/inference_get_video.yml b/specification/resources/inference/examples/go/inference_get_video.yml new file mode 100644 index 000000000..6a2458c03 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_get_video.yml @@ -0,0 +1,23 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + job, _, err := client.Video.Generations.Get(ctx, os.Getenv("VIDEO_ID")) + if err != nil { + panic(err) + } + + fmt.Println(job.ID, job.Status) + } diff --git a/specification/resources/inference/examples/go/inference_get_video_content.yml b/specification/resources/inference/examples/go/inference_get_video_content.yml new file mode 100644 index 000000000..601bfdac7 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_get_video_content.yml @@ -0,0 +1,25 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + raw, _, err := client.Video.Generations.Content(ctx, os.Getenv("VIDEO_ID")) + if err != nil { + panic(err) + } + if err := os.WriteFile("output.mp4", raw, 0644); err != nil { + panic(err) + } + fmt.Println("Wrote output.mp4") + } diff --git a/specification/resources/inference/examples/go/inference_list_batches.yml b/specification/resources/inference/examples/go/inference_list_batches.yml new file mode 100644 index 000000000..bfdedbce7 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_list_batches.yml @@ -0,0 +1,31 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + resp, _, err := client.BatchInference.ListJobs(ctx, &godo.ListBatchesOptions{ + Limit: 20, + }) + if err != nil { + panic(err) + } + + for _, edge := range resp.Edges { + b := edge.Node + fmt.Printf("%s\t%s\t%s\n", b.BatchID, b.Status, b.CreatedAt) + } + + fmt.Println("has_next_page:", resp.PageInfo.HasNextPage) + fmt.Println("end_cursor: ", resp.PageInfo.EndCursor) + } diff --git a/specification/resources/inference/examples/go/inference_list_models.yml b/specification/resources/inference/examples/go/inference_list_models.yml new file mode 100644 index 000000000..e8d9d5783 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_list_models.yml @@ -0,0 +1,25 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + page, _, err := client.Models.List(ctx) + if err != nil { + panic(err) + } + + for _, model := range page.Data { + fmt.Println(model.ID) + } + } diff --git a/specification/resources/inference/examples/go/inference_upload_batch_file.yml b/specification/resources/inference/examples/go/inference_upload_batch_file.yml new file mode 100644 index 000000000..06f6b0f68 --- /dev/null +++ b/specification/resources/inference/examples/go/inference_upload_batch_file.yml @@ -0,0 +1,38 @@ +lang: Go +source: |- + package main + + import ( + "context" + "fmt" + "os" + + "github.com/digitalocean/godo" + ) + + func main() { + // Two-step upload flow: + // 1. Reserve a file_id + presigned upload_url via CreatePresignedUploadURL. + // 2. PUT the raw JSONL bytes with UploadInputFile. + client := godo.NewFromToken(os.Getenv("DIGITALOCEAN_TOKEN")) + ctx := context.Background() + + intent, _, err := client.BatchInference.CreatePresignedUploadURL(ctx, &godo.CreateBatchFileRequest{ + FileName: "batch_requests.jsonl", + }) + if err != nil { + panic(err) + } + + fh, err := os.Open("batch_requests.jsonl") + if err != nil { + panic(err) + } + defer fh.Close() + + if _, err := client.BatchInference.UploadInputFile(ctx, intent.UploadURL, fh); err != nil { + panic(err) + } + + fmt.Println("uploaded file_id:", intent.FileID) + } diff --git a/specification/resources/inference/examples/python/inference_create_speech.yml b/specification/resources/inference/examples/python/inference_create_speech.yml new file mode 100644 index 000000000..46e28a161 --- /dev/null +++ b/specification/resources/inference/examples/python/inference_create_speech.yml @@ -0,0 +1,19 @@ +lang: Python +source: |- + import base64 + import os + from pydo.inference import Client + + client = Client(token=os.environ.get("DIGITALOCEAN_TOKEN")) + + response = client.audio.speech.create( + model="qwen3-tts-voicedesign", + input="Hello, world!", + voice="alloy", + response_format="mp3", + instructions="Speak naturally.", + ) + + audio_bytes = base64.b64decode(response.data[0].b64_json) + with open("output.mp3", "wb") as f: + f.write(audio_bytes) diff --git a/specification/resources/inference/examples/python/inference_create_video.yml b/specification/resources/inference/examples/python/inference_create_video.yml new file mode 100644 index 000000000..2402b6fce --- /dev/null +++ b/specification/resources/inference/examples/python/inference_create_video.yml @@ -0,0 +1,15 @@ +lang: Python +source: |- + import os + from pydo.inference import Client + + client = Client(token=os.environ.get("DIGITALOCEAN_TOKEN")) + + job = client.video.generations.create( + model="wan2-2-t2v-a14b", + prompt="Two anthropomorphic cats in boxing gear fight intensely on a spotlighted stage", + size="1280x720", + fps=16, + ) + + print(job.id, job.status) diff --git a/specification/resources/inference/examples/python/inference_get_video.yml b/specification/resources/inference/examples/python/inference_get_video.yml new file mode 100644 index 000000000..614d67400 --- /dev/null +++ b/specification/resources/inference/examples/python/inference_get_video.yml @@ -0,0 +1,9 @@ +lang: Python +source: |- + import os + from pydo.inference import Client + + client = Client(token=os.environ.get("DIGITALOCEAN_TOKEN")) + + job = client.video.generations.retrieve(os.environ["VIDEO_ID"]) + print(job.id, job.status) diff --git a/specification/resources/inference/examples/python/inference_get_video_content.yml b/specification/resources/inference/examples/python/inference_get_video_content.yml new file mode 100644 index 000000000..fef181f19 --- /dev/null +++ b/specification/resources/inference/examples/python/inference_get_video_content.yml @@ -0,0 +1,11 @@ +lang: Python +source: |- + import os + import requests + + headers = {"Authorization": f"Bearer {os.environ['DIGITALOCEAN_TOKEN']}"} + url = f"https://inference.do-ai.run/v1/videos/{os.environ['VIDEO_ID']}/content" + resp = requests.get(url, headers=headers) + resp.raise_for_status() + with open("output.mp4", "wb") as f: + f.write(resp.content) diff --git a/specification/resources/inference/inference_async_invoke.yml b/specification/resources/inference/inference_async_invoke.yml index 104e4147b..0b41ed91b 100644 --- a/specification/resources/inference/inference_async_invoke.yml +++ b/specification/resources/inference/inference_async_invoke.yml @@ -76,6 +76,7 @@ responses: x-codeSamples: - $ref: 'examples/curl/inference_async_invoke.yml' - $ref: 'examples/python/inference_async_invoke.yml' + - $ref: 'examples/go/inference_async_invoke.yml' - $ref: 'examples/dots/inference_async_invoke.yml' security: - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_cancel_batch.yml b/specification/resources/inference/inference_cancel_batch.yml index a7c5b6b5e..3a3e6874e 100644 --- a/specification/resources/inference/inference_cancel_batch.yml +++ b/specification/resources/inference/inference_cancel_batch.yml @@ -58,6 +58,7 @@ responses: x-codeSamples: - $ref: 'examples/curl/inference_cancel_batch.yml' - $ref: 'examples/python/inference_cancel_batch.yml' + - $ref: 'examples/go/inference_cancel_batch.yml' - $ref: 'examples/dots/inference_cancel_batch.yml' security: - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_create_batch.yml b/specification/resources/inference/inference_create_batch.yml index a2b4f6d02..134e722af 100644 --- a/specification/resources/inference/inference_create_batch.yml +++ b/specification/resources/inference/inference_create_batch.yml @@ -80,6 +80,7 @@ responses: x-codeSamples: - $ref: 'examples/curl/inference_create_batch.yml' - $ref: 'examples/python/inference_create_batch.yml' + - $ref: 'examples/go/inference_create_batch.yml' - $ref: 'examples/dots/inference_create_batch.yml' security: - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_create_batch_file.yml b/specification/resources/inference/inference_create_batch_file.yml index 13e4702b0..662692c96 100644 --- a/specification/resources/inference/inference_create_batch_file.yml +++ b/specification/resources/inference/inference_create_batch_file.yml @@ -52,6 +52,7 @@ responses: x-codeSamples: - $ref: 'examples/curl/inference_create_batch_file.yml' - $ref: 'examples/python/inference_create_batch_file.yml' + - $ref: 'examples/go/inference_create_batch_file.yml' - $ref: 'examples/dots/inference_create_batch_file.yml' security: - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_create_chat_completion.yml b/specification/resources/inference/inference_create_chat_completion.yml index fe9199277..f8dc1de76 100644 --- a/specification/resources/inference/inference_create_chat_completion.yml +++ b/specification/resources/inference/inference_create_chat_completion.yml @@ -41,6 +41,10 @@ responses: x-codeSamples: - $ref: 'examples/curl/inference_create_chat_completion.yml' - $ref: 'examples/python/inference_create_chat_completion.yml' + - $ref: 'examples/go/inference_create_chat_completion.yml' + - $ref: 'examples/go/inference_create_chat_completion_mcp.yml' + - $ref: 'examples/go/inference_create_chat_completion_vlm.yml' + - $ref: 'examples/go/inference_create_chat_completion_kb.yml' - $ref: 'examples/dots/inference_create_chat_completion.yml' security: - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_create_embeddings.yml b/specification/resources/inference/inference_create_embeddings.yml index 0f29542f8..31dfc972f 100644 --- a/specification/resources/inference/inference_create_embeddings.yml +++ b/specification/resources/inference/inference_create_embeddings.yml @@ -41,6 +41,7 @@ responses: x-codeSamples: - $ref: 'examples/curl/inference_create_embeddings.yml' - $ref: 'examples/python/inference_create_embeddings.yml' + - $ref: 'examples/go/inference_create_embeddings.yml' - $ref: 'examples/dots/inference_create_embeddings.yml' security: - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_create_image.yml b/specification/resources/inference/inference_create_image.yml index ec598cd2f..7896b8228 100644 --- a/specification/resources/inference/inference_create_image.yml +++ b/specification/resources/inference/inference_create_image.yml @@ -40,6 +40,7 @@ responses: x-codeSamples: - $ref: 'examples/curl/inference_create_image.yml' - $ref: 'examples/python/inference_create_image.yml' + - $ref: 'examples/go/inference_create_image.yml' - $ref: 'examples/dots/inference_create_image.yml' security: - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_create_messages.yml b/specification/resources/inference/inference_create_messages.yml index 3b4983ad9..2b5170b94 100644 --- a/specification/resources/inference/inference_create_messages.yml +++ b/specification/resources/inference/inference_create_messages.yml @@ -59,6 +59,7 @@ responses: x-codeSamples: - $ref: 'examples/curl/inference_create_messages.yml' - $ref: 'examples/python/inference_create_messages.yml' + - $ref: 'examples/go/inference_create_messages.yml' - $ref: 'examples/dots/inference_create_messages.yml' security: - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_create_response.yml b/specification/resources/inference/inference_create_response.yml index 50481de77..ca3cc181a 100644 --- a/specification/resources/inference/inference_create_response.yml +++ b/specification/resources/inference/inference_create_response.yml @@ -42,6 +42,11 @@ responses: x-codeSamples: - $ref: 'examples/curl/inference_create_response.yml' - $ref: 'examples/python/inference_create_response.yml' + - $ref: 'examples/go/inference_create_response.yml' + - $ref: 'examples/go/inference_create_response_web_search.yml' + - $ref: 'examples/go/inference_create_response_web_fetch.yml' + - $ref: 'examples/go/inference_create_response_model_synthesis.yml' + - $ref: 'examples/go/inference_create_response_tool_search.yml' - $ref: 'examples/dots/inference_create_response.yml' security: - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_create_speech.yml b/specification/resources/inference/inference_create_speech.yml new file mode 100644 index 000000000..ff5de6366 --- /dev/null +++ b/specification/resources/inference/inference_create_speech.yml @@ -0,0 +1,59 @@ +operationId: inference_create_speech +summary: Generate speech from text +description: > + Convert text input to speech audio. The response may be raw audio bytes + (`audio/mpeg`, `audio/wav`, and similar) or a JSON envelope with + base64-encoded audio in `data[].b64_json`. +tags: + - Serverless Inference +servers: + - url: "https://inference.do-ai.run" + description: production +x-inference-base-url: "https://inference.do-ai.run" +requestBody: + required: true + content: + application/json: + schema: + $ref: "models/create_speech_request.yml" +responses: + "200": + description: Successful speech generation. + headers: + ratelimit-limit: + $ref: '../../shared/headers.yml#/ratelimit-limit' + ratelimit-remaining: + $ref: '../../shared/headers.yml#/ratelimit-remaining' + ratelimit-reset: + $ref: '../../shared/headers.yml#/ratelimit-reset' + content: + application/json: + schema: + $ref: "models/speech_response.yml" + audio/mpeg: + schema: + type: string + format: binary + audio/wav: + schema: + type: string + format: binary + audio/mp3: + schema: + type: string + format: binary + "401": + $ref: '../../shared/responses/unauthorized.yml' + "429": + $ref: '../../shared/responses/too_many_requests.yml' + "500": + $ref: '../../shared/responses/server_error.yml' + default: + $ref: '../../shared/responses/unexpected_error.yml' +x-codeSamples: + - $ref: 'examples/curl/inference_create_speech.yml' + - $ref: 'examples/python/inference_create_speech.yml' + - $ref: 'examples/go/inference_create_speech.yml' + - $ref: 'examples/dots/inference_create_speech.yml' +security: + - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_create_video.yml b/specification/resources/inference/inference_create_video.yml new file mode 100644 index 000000000..1fa2036a3 --- /dev/null +++ b/specification/resources/inference/inference_create_video.yml @@ -0,0 +1,48 @@ +operationId: inference_create_video +summary: Start a video generation job +description: > + Start an asynchronous video generation job from a text prompt. Poll + `GET /v1/videos/{video_id}` until the job reaches a terminal status, then + download the MP4 with `GET /v1/videos/{video_id}/content` or from + `output.url` when present. +tags: + - Serverless Inference +servers: + - url: "https://inference.do-ai.run" + description: production +x-inference-base-url: "https://inference.do-ai.run" +requestBody: + required: true + content: + application/json: + schema: + $ref: "models/create_video_request.yml" +responses: + "200": + description: Video generation job accepted. + headers: + ratelimit-limit: + $ref: '../../shared/headers.yml#/ratelimit-limit' + ratelimit-remaining: + $ref: '../../shared/headers.yml#/ratelimit-remaining' + ratelimit-reset: + $ref: '../../shared/headers.yml#/ratelimit-reset' + content: + application/json: + schema: + $ref: "models/video_generation.yml" + "401": + $ref: '../../shared/responses/unauthorized.yml' + "429": + $ref: '../../shared/responses/too_many_requests.yml' + "500": + $ref: '../../shared/responses/server_error.yml' + default: + $ref: '../../shared/responses/unexpected_error.yml' +x-codeSamples: + - $ref: 'examples/curl/inference_create_video.yml' + - $ref: 'examples/python/inference_create_video.yml' + - $ref: 'examples/go/inference_create_video.yml' + - $ref: 'examples/dots/inference_create_video.yml' +security: + - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_get_batch.yml b/specification/resources/inference/inference_get_batch.yml index 35c025f72..9d90db28c 100644 --- a/specification/resources/inference/inference_get_batch.yml +++ b/specification/resources/inference/inference_get_batch.yml @@ -47,6 +47,7 @@ responses: x-codeSamples: - $ref: 'examples/curl/inference_get_batch.yml' - $ref: 'examples/python/inference_get_batch.yml' + - $ref: 'examples/go/inference_get_batch.yml' - $ref: 'examples/dots/inference_get_batch.yml' security: - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_get_batch_results.yml b/specification/resources/inference/inference_get_batch_results.yml index 644bf4e74..8700d75d4 100644 --- a/specification/resources/inference/inference_get_batch_results.yml +++ b/specification/resources/inference/inference_get_batch_results.yml @@ -70,6 +70,7 @@ responses: x-codeSamples: - $ref: 'examples/curl/inference_get_batch_results.yml' - $ref: 'examples/python/inference_get_batch_results.yml' + - $ref: 'examples/go/inference_get_batch_results.yml' - $ref: 'examples/dots/inference_get_batch_results.yml' security: - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_get_video.yml b/specification/resources/inference/inference_get_video.yml new file mode 100644 index 000000000..5efeca715 --- /dev/null +++ b/specification/resources/inference/inference_get_video.yml @@ -0,0 +1,50 @@ +operationId: inference_get_video +summary: Retrieve a video generation job +description: > + Returns the current state of a video generation job. Poll until `status` + reaches a terminal value such as `completed` or `failed`. +tags: + - Serverless Inference +servers: + - url: "https://inference.do-ai.run" + description: production +x-inference-base-url: "https://inference.do-ai.run" +parameters: + - in: path + name: video_id + description: The video generation job identifier. + required: true + schema: + type: string + example: "video_bGl0ZWxsbTpjdXN0b21fbGxtX3Byb3ZpZGVyOm9wZW5haTttb2RlbF9pZDo7dmlkZW9faWQ6ZGExYjFmYzMtYTM3NC00MmM0LTgxMWMtOWE5NmE3ZWY0OTIz" +responses: + "200": + description: The video generation job. + headers: + ratelimit-limit: + $ref: '../../shared/headers.yml#/ratelimit-limit' + ratelimit-remaining: + $ref: '../../shared/headers.yml#/ratelimit-remaining' + ratelimit-reset: + $ref: '../../shared/headers.yml#/ratelimit-reset' + content: + application/json: + schema: + $ref: "models/video_generation.yml" + "401": + $ref: '../../shared/responses/unauthorized.yml' + "404": + $ref: '../../shared/responses/not_found.yml' + "429": + $ref: '../../shared/responses/too_many_requests.yml' + "500": + $ref: '../../shared/responses/server_error.yml' + default: + $ref: '../../shared/responses/unexpected_error.yml' +x-codeSamples: + - $ref: 'examples/curl/inference_get_video.yml' + - $ref: 'examples/python/inference_get_video.yml' + - $ref: 'examples/go/inference_get_video.yml' + - $ref: 'examples/dots/inference_get_video.yml' +security: + - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_get_video_content.yml b/specification/resources/inference/inference_get_video_content.yml new file mode 100644 index 000000000..c4f6ed300 --- /dev/null +++ b/specification/resources/inference/inference_get_video_content.yml @@ -0,0 +1,50 @@ +operationId: inference_get_video_content +summary: Download generated video content +description: > + Downloads the generated MP4 for a completed video generation job. +tags: + - Serverless Inference +servers: + - url: "https://inference.do-ai.run" + description: production +x-inference-base-url: "https://inference.do-ai.run" +parameters: + - in: path + name: video_id + description: The video generation job identifier. + required: true + schema: + type: string + example: "video_bGl0ZWxsbTpjdXN0b21fbGxtX3Byb3ZpZGVyOm9wZW5haTttb2RlbF9pZDo7dmlkZW9faWQ6ZGExYjFmYzMtYTM3NC00MmM0LTgxMWMtOWE5NmE3ZWY0OTIz" +responses: + "200": + description: Binary MP4 content. + headers: + ratelimit-limit: + $ref: '../../shared/headers.yml#/ratelimit-limit' + ratelimit-remaining: + $ref: '../../shared/headers.yml#/ratelimit-remaining' + ratelimit-reset: + $ref: '../../shared/headers.yml#/ratelimit-reset' + content: + video/mp4: + schema: + type: string + format: binary + "401": + $ref: '../../shared/responses/unauthorized.yml' + "404": + $ref: '../../shared/responses/not_found.yml' + "429": + $ref: '../../shared/responses/too_many_requests.yml' + "500": + $ref: '../../shared/responses/server_error.yml' + default: + $ref: '../../shared/responses/unexpected_error.yml' +x-codeSamples: + - $ref: 'examples/curl/inference_get_video_content.yml' + - $ref: 'examples/python/inference_get_video_content.yml' + - $ref: 'examples/go/inference_get_video_content.yml' + - $ref: 'examples/dots/inference_get_video_content.yml' +security: + - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_list_batches.yml b/specification/resources/inference/inference_list_batches.yml index 85b57b136..e5d1b814e 100644 --- a/specification/resources/inference/inference_list_batches.yml +++ b/specification/resources/inference/inference_list_batches.yml @@ -76,6 +76,7 @@ responses: x-codeSamples: - $ref: 'examples/curl/inference_list_batches.yml' - $ref: 'examples/python/inference_list_batches.yml' + - $ref: 'examples/go/inference_list_batches.yml' - $ref: 'examples/dots/inference_list_batches.yml' security: - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_list_models.yml b/specification/resources/inference/inference_list_models.yml index 002321f2f..da01b7924 100644 --- a/specification/resources/inference/inference_list_models.yml +++ b/specification/resources/inference/inference_list_models.yml @@ -31,6 +31,7 @@ responses: x-codeSamples: - $ref: 'examples/curl/inference_list_models.yml' - $ref: 'examples/python/inference_list_models.yml' + - $ref: 'examples/go/inference_list_models.yml' - $ref: 'examples/dots/inference_list_models.yml' security: - inference_bearer_auth: [] diff --git a/specification/resources/inference/inference_upload_batch_file.yml b/specification/resources/inference/inference_upload_batch_file.yml index 6b17da9ac..7085d1ed8 100644 --- a/specification/resources/inference/inference_upload_batch_file.yml +++ b/specification/resources/inference/inference_upload_batch_file.yml @@ -70,5 +70,6 @@ responses: x-codeSamples: - $ref: 'examples/curl/inference_upload_batch_file.yml' - $ref: 'examples/python/inference_upload_batch_file.yml' + - $ref: 'examples/go/inference_upload_batch_file.yml' - $ref: 'examples/dots/inference_upload_batch_file.yml' security: [] diff --git a/specification/resources/inference/models/create_speech_request.yml b/specification/resources/inference/models/create_speech_request.yml new file mode 100644 index 000000000..4e0f19e4f --- /dev/null +++ b/specification/resources/inference/models/create_speech_request.yml @@ -0,0 +1,29 @@ +type: object +description: Request body for text-to-speech generation. +required: + - model + - input +properties: + model: + type: string + description: The text-to-speech model to use. + example: "qwen3-tts-voicedesign" + input: + type: string + minLength: 1 + description: The text to convert to speech. + example: "Hello, world!" + voice: + type: string + description: The voice to use for synthesis. + example: "alloy" + response_format: + type: string + description: > + The audio format to return. Supported values include `mp3` and `wav`. + The API may return raw audio bytes or a JSON envelope with base64-encoded audio. + example: "mp3" + instructions: + type: string + description: Optional style or delivery instructions for the synthesizer. + example: "Speak naturally." diff --git a/specification/resources/inference/models/create_video_request.yml b/specification/resources/inference/models/create_video_request.yml new file mode 100644 index 000000000..1535badb5 --- /dev/null +++ b/specification/resources/inference/models/create_video_request.yml @@ -0,0 +1,24 @@ +type: object +description: Request body to start an asynchronous video generation job. +required: + - model + - prompt +properties: + model: + type: string + description: The video generation model to use. + example: "wan2-2-t2v-a14b" + prompt: + type: string + minLength: 1 + description: A text description of the desired video. + example: "Two anthropomorphic cats in boxing gear fight intensely on a spotlighted stage" + size: + type: string + description: The output resolution, for example `1280x720`. + example: "1280x720" + fps: + type: integer + minimum: 1 + description: Frames per second for the generated video. + example: 16 diff --git a/specification/resources/inference/models/speech_audio_item.yml b/specification/resources/inference/models/speech_audio_item.yml new file mode 100644 index 000000000..860e269e1 --- /dev/null +++ b/specification/resources/inference/models/speech_audio_item.yml @@ -0,0 +1,9 @@ +type: object +description: A single audio payload in a JSON speech response envelope. +required: + - b64_json +properties: + b64_json: + type: string + description: Base64-encoded audio bytes. + example: "//uQxAAAA..." diff --git a/specification/resources/inference/models/speech_response.yml b/specification/resources/inference/models/speech_response.yml new file mode 100644 index 000000000..28d6d9615 --- /dev/null +++ b/specification/resources/inference/models/speech_response.yml @@ -0,0 +1,17 @@ +type: object +description: > + JSON envelope for text-to-speech when the endpoint returns `application/json`. + The live endpoint may instead return raw audio bytes with an `audio/*` Content-Type. +required: + - data +properties: + created: + type: integer + description: Unix timestamp (in seconds) of when the audio was created. + example: 1710700000 + data: + type: array + minItems: 1 + description: Generated audio items. + items: + $ref: "speech_audio_item.yml" diff --git a/specification/resources/inference/models/video_generation.yml b/specification/resources/inference/models/video_generation.yml new file mode 100644 index 000000000..0f6e36eeb --- /dev/null +++ b/specification/resources/inference/models/video_generation.yml @@ -0,0 +1,40 @@ +type: object +description: Status of an asynchronous video generation job. +required: + - id + - status +properties: + id: + type: string + description: The video generation job identifier. + example: "video_bGl0ZWxsbTpjdXN0b21fbGxtX3Byb3ZpZGVyOm9wZW5haTttb2RlbF9pZDo7dmlkZW9faWQ6ZGExYjFmYzMtYTM3NC00MmM0LTgxMWMtOWE5NmE3ZWY0OTIz" + object: + type: string + description: Object type returned by the API. + example: "video" + created_at: + type: integer + description: Unix timestamp (in seconds) of when the job was created. + example: 1777003604 + model: + type: string + description: The model used for generation. + example: "wan2.2-t2v-a14b" + status: + type: string + description: > + Job status. Poll until the value is a terminal state such as `completed` or `failed`. + example: "processing" + output: + nullable: true + allOf: + - $ref: "video_generation_output.yml" + error: + type: object + nullable: true + description: Error details when status is `failed`. + additionalProperties: true + x_request_id: + type: string + nullable: true + description: Request correlation identifier when provided by the API. diff --git a/specification/resources/inference/models/video_generation_output.yml b/specification/resources/inference/models/video_generation_output.yml new file mode 100644 index 000000000..ecf51160d --- /dev/null +++ b/specification/resources/inference/models/video_generation_output.yml @@ -0,0 +1,8 @@ +type: object +description: Download location for a completed video when a presigned URL is available. +properties: + url: + type: string + format: uri + description: Presigned URL for the generated MP4. + example: "https://example.com/output.mp4"