diff --git a/.netconfig b/.netconfig index 9b8300f..cbb6061 100644 --- a/.netconfig +++ b/.netconfig @@ -152,8 +152,8 @@ weak [file "src/xAI.Protocol/chat.proto"] url = https://github.com/xai-org/xai-proto/blob/main/proto/xai/api/v1/chat.proto - sha = 17a2da08cbbf89aa1f33ffe58b687fe0b2d50468 - etag = e7da2c915664caf64c0da7d886826de37fcf98753cf613a6ad8aad96f6ddcda5 + sha = 2c2df4f5d9429f5f21e58bb9e63285c69bcc144f + etag = 061acaded15e83e3056dfcb1a738cd6aa0cad27f7f6ec38b6bf84e3077d448ac weak [file "src/xAI.Protocol/deferred.proto"] url = https://github.com/xai-org/xai-proto/blob/main/proto/xai/api/v1/deferred.proto @@ -172,8 +172,8 @@ weak [file "src/xAI.Protocol/image.proto"] url = https://github.com/xai-org/xai-proto/blob/main/proto/xai/api/v1/image.proto - sha = d67bcf3e661aa9641af9750632fa1c38ea974da1 - etag = 3ea27e240320c26d14b8c64d00f236c078127ebdb6fa957efc49232dfd75a20c + sha = 2c2df4f5d9429f5f21e58bb9e63285c69bcc144f + etag = 3d66f35d2e1555c6eae2218705b6f8ee5fa6537939b6ae0a18e0a2fd13a81bff weak [file "src/xAI.Protocol/models.proto"] url = https://github.com/xai-org/xai-proto/blob/main/proto/xai/api/v1/models.proto @@ -192,13 +192,13 @@ weak [file "src/xAI.Protocol/usage.proto"] url = https://github.com/xai-org/xai-proto/blob/main/proto/xai/api/v1/usage.proto - sha = d8def643bea79ad10f5a678d70ae37edca26490f - etag = 74c44beb7bfd2e75ea0524ff9be820cc067e009b071dee59869a16d372280a0a + sha = 2c2df4f5d9429f5f21e58bb9e63285c69bcc144f + etag = 0bf9577be87d3cfc79895971071ef1eaa78645cb784462e7e90bff03440dfff4 weak [file "src/xAI.Protocol/video.proto"] url = https://github.com/xai-org/xai-proto/blob/main/proto/xai/api/v1/video.proto - sha = 43a1b6b731943b8f031c2f2d946f7183f0933ffd - etag = 37562e78a6d64800b09c643632a33b6bc902955b491114bd5b6ec957d23d6e64 + sha = 723dd2aa22d17be35617463837dc47cda008d90e + etag = 24af69223d5fafc1ae8554f1ee43fdb0ff8c1eeacfa2e8ce9719fd58179d2fb8 weak [file "src/xAI.Protocol/google/protobuf/timestamp.proto"] url = https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/timestamp.proto @@ -233,6 +233,6 @@ weak [file "src/xAI.Protocol/files.proto"] url = https://github.com/xai-org/xai-proto/blob/main/proto/xai/api/v1/files.proto - etag = 4c91f851b288a225acfc1173f2f8853a1b550da1e97d2fdcec99debb5f8fac43 + etag = b5e8ed748220b2fa727e8845f09f612cb77813d02c4260b77e6464aa0c98d57f weak - sha = 0c0f5353aa7ab2a4ffea310f9d9364ed5c424af2 + sha = c666ac39e9a8f562e94b2b57872a75bc1438ec2b diff --git a/readme.md b/readme.md index aa1edae..01dfe77 100644 --- a/readme.md +++ b/readme.md @@ -618,7 +618,6 @@ Uses your own API Key. [![DRIVE.NET, Inc.](https://avatars.githubusercontent.com/u/15047123?v=4&s=39 "DRIVE.NET, Inc.")](https://github.com/drivenet) [![Keith Pickford](https://avatars.githubusercontent.com/u/16598898?u=64416b80caf7092a885f60bb31612270bffc9598&v=4&s=39 "Keith Pickford")](https://github.com/Keflon) [![Thomas Bolon](https://avatars.githubusercontent.com/u/127185?u=7f50babfc888675e37feb80851a4e9708f573386&v=4&s=39 "Thomas Bolon")](https://github.com/tbolon) -[![Kori Francis](https://avatars.githubusercontent.com/u/67574?u=3991fb983e1c399edf39aebc00a9f9cd425703bd&v=4&s=39 "Kori Francis")](https://github.com/kfrancis) [![Reuben Swartz](https://avatars.githubusercontent.com/u/724704?u=2076fe336f9f6ad678009f1595cbea434b0c5a41&v=4&s=39 "Reuben Swartz")](https://github.com/rbnswartz) [![Jacob Foshee](https://avatars.githubusercontent.com/u/480334?v=4&s=39 "Jacob Foshee")](https://github.com/jfoshee) [![](https://avatars.githubusercontent.com/u/33566379?u=bf62e2b46435a267fa246a64537870fd2449410f&v=4&s=39 "")](https://github.com/Mrxx99) diff --git a/src/xAI.Protocol/chat.proto b/src/xAI.Protocol/chat.proto index 14001bf..5ead2df 100644 --- a/src/xAI.Protocol/chat.proto +++ b/src/xAI.Protocol/chat.proto @@ -1,14 +1,13 @@ syntax = "proto3"; -option csharp_namespace = "xAI.Protocol"; package xai_api; import "google/protobuf/timestamp.proto"; -import "deferred.proto"; -import "documents.proto"; -import "image.proto"; -import "sample.proto"; -import "usage.proto"; +import "xai/api/v1/deferred.proto"; +import "xai/api/v1/documents.proto"; +import "xai/api/v1/image.proto"; +import "xai/api/v1/sample.proto"; +import "xai/api/v1/usage.proto"; // An API that exposes our language models via a Chat interface. service Chat { @@ -144,7 +143,7 @@ message GetCompletionsRequest { // new topics. optional float presence_penalty = 9; - // Constrains effort on reasoning for reasoning models. Default to `EFFORT_MEDIUM`. + // Constrains effort on reasoning for reasoning models. Defaults vary by model (e.g. `grok-4.5` and `grok-4.6` default to `EFFORT_HIGH`). optional ReasoningEffort reasoning_effort = 19; // Set the parameters to be used for realtime data. If not set, no realtime data will be acquired by the model. @@ -609,6 +608,7 @@ enum ReasoningEffort { EFFORT_MEDIUM = 2; EFFORT_HIGH = 3; EFFORT_NONE = 4; + EFFORT_XHIGH = 5; } // Number of agents to use for multi-agent models. @@ -672,6 +672,8 @@ message Tool { MCP mcp = 7; // Built in attachment search. AttachmentSearch attachment_search = 8; + // Built in image generation. + ImageGeneration image_generation = 10; } } @@ -767,6 +769,13 @@ message XSearch { message CodeExecution {} +message ImageGeneration { + // Which image capabilities to expose to the model. One of "auto" (the default; + // both generation and editing), "generate" (text-to-image only), or + // "edit" (image editing only). + optional string action = 1; +} + message CollectionsSearch { // The ID(s) of the source collection(s) within which the search should be performed. // A maximum of 10 collections IDs can be used for search. @@ -839,6 +848,10 @@ enum ToolCallType { // Indicates the tool is a server-side attachment_search tool, and client side won't need to execute. // Maps to `attachment_search_call` type in OAI Responses API. TOOL_CALL_TYPE_ATTACHMENT_SEARCH_TOOL = 7; + + // Indicates the tool is a server-side image_generation tool, and client side won't need to execute. + // Maps to `image_generation_call` type in OAI Responses API. + TOOL_CALL_TYPE_IMAGE_GENERATION_TOOL = 10; } enum ToolCallStatus { @@ -1059,7 +1072,7 @@ message RequestSettings { // The ID of the previous response from the model. optional string previous_response_id = 3; - // Constrains effort on reasoning for reasoning models. Default to `EFFORT_MEDIUM`. + // Constrains effort on reasoning for reasoning models. Defaults vary by model (e.g. `grok-4.5` and `grok-4.6` default to `EFFORT_HIGH`). optional ReasoningEffort reasoning_effort = 4; // A number between 0 and 2 used to control the variance of completions. diff --git a/src/xAI.Protocol/files.proto b/src/xAI.Protocol/files.proto index f4a7d56..db8d45e 100644 --- a/src/xAI.Protocol/files.proto +++ b/src/xAI.Protocol/files.proto @@ -1,5 +1,4 @@ syntax = "proto3"; -option csharp_namespace = "xAI.Protocol"; package xai_api; @@ -36,6 +35,45 @@ service Files { // Stream the file's contents in chunks of up to 5 MB, in order. // Concatenate `data` from every chunk to reconstruct the file. rpc RetrieveFileContent(RetrieveFileContentRequest) returns (stream FileContentChunk) {} + + // Create a public, unauthenticated URL for a file, accessible without an + // API key. Only images, videos, and PDFs can be made public. + // + // A file can have at most one public URL at a time. Calling this on a + // file that already has a public URL returns the existing URL. To update + // the expiry, call again with a new `expires_after` value. + // + // **Public URL expiry behavior:** + // + // - If `expires_after` is set, the public URL expires that many seconds + // from now, independently of the file's own TTL. + // - If `expires_after` is omitted and the file has a TTL + // (`UploadFileInit.expires_after` was set at upload), the public URL + // automatically inherits the file's expiry — it will expire at the + // same time as the file. + // - If `expires_after` is omitted and the file has no TTL, the public + // URL remains valid indefinitely (until explicitly revoked or the file + // is deleted). + // + // **Automatic revocation:** + // + // A public URL is automatically revoked when the file is deleted (by the + // user or by TTL expiry). Revocation may not take effect immediately, so + // the URL can remain accessible for a short period after the file or the + // public URL expires. Call `RevokePublicUrl` to revoke immediately. + rpc CreatePublicUrl(CreatePublicUrlRequest) returns (CreatePublicUrlResponse) {} + + // Revoke the public URL for a file. After revocation the public URL is + // no longer accessible, while the original file remains accessible via + // authenticated endpoints. + // + // Public URLs are also automatically revoked when the file is deleted, + // when the file's TTL elapses, or when the public URL's own expiry + // elapses. Automatic revocation may not take effect immediately; use this + // RPC to revoke a public URL right away. + // + // Returns success if the file has no public URL (nothing to revoke). + rpc RevokePublicUrl(RevokePublicUrlRequest) returns (RevokePublicUrlResponse) {} } // First stream message of an `UploadFile` call. Sent exactly once, before @@ -84,6 +122,14 @@ message File { string id = 5; reserved 6; + + // Public URL for the file. Only present when the file has an active + // public URL (created via CreatePublicUrl or storage_options.public_url). + optional string public_url = 7; + + // When the public URL expires. Only present when public_url is set + // and has an independent expiry. + optional google.protobuf.Timestamp public_url_expires_at = 8; } // Sort direction for list-style RPCs. @@ -119,6 +165,16 @@ message ListFilesRequest { // Sort field. Defaults to `FILES_SORT_BY_CREATED_AT`. optional FilesSortBy sort_by = 4; + + // AIP-160 filter expression to narrow down results. + // Supported fields: file_id, name (or file_name), size_bytes, + // content_type, created_at, expires_at, upload_status, user_defined_id. + // Operators: =, !=, >, >=, <, <=, AND, OR, NOT. + // Examples: + // - 'name:"report"' + // - 'content_type = "application/pdf"' + // - 'size_bytes > 1000000 AND created_at > "2024-01-01T00:00:00Z"' + optional string filter = 5; } // Response message for `Files.ListFiles`. @@ -179,3 +235,48 @@ message FileContentChunk { // Up to 5 MB of file bytes. Final/intermediate chunks may be smaller. bytes data = 1; } + +// Request message for `Files.CreatePublicUrl`. +message CreatePublicUrlRequest { + // The ID of the file to create a public URL for. + string file_id = 1; + + // Seconds from now until the public URL expires. Must be between 3600 + // (1 hour) and 2592000 (30 days). + // + // If omitted and the file has a TTL, the public URL inherits the file's + // expiry. If omitted and the file has no TTL, the public URL remains + // valid indefinitely until the file is deleted or the URL is explicitly + // revoked via `RevokePublicUrl`. + optional int64 expires_after = 2; +} + +// Response message for `Files.CreatePublicUrl`. +message CreatePublicUrlResponse { + // The full public URL that can be shared and accessed without an API key. + string public_url = 1; + + // When the public URL expires. Present when the public URL has an expiry, + // either from an explicit `expires_after` in the request or inherited from + // the file's TTL. Absent when the public URL is valid indefinitely. + optional google.protobuf.Timestamp expires_at = 2; +} + +// Request message for `Files.RevokePublicUrl`. +message RevokePublicUrlRequest { + // The ID of the file whose public URL should be revoked. + string file_id = 1; +} + +// Response message for `Files.RevokePublicUrl`. +message RevokePublicUrlResponse { + // The file ID whose public URL was revoked. + string file_id = 1; + + // True if a public URL was actually revoked. False if the file had + // no active public URL (no-op). + bool revoked = 2; + + // The full public URL that was revoked. Only present when revoked is true. + optional string public_url = 3; +} diff --git a/src/xAI.Protocol/image.proto b/src/xAI.Protocol/image.proto index 325339f..09a72b9 100644 --- a/src/xAI.Protocol/image.proto +++ b/src/xAI.Protocol/image.proto @@ -1,9 +1,9 @@ syntax = "proto3"; -option csharp_namespace = "xAI.Protocol"; package xai_api; -import "usage.proto"; +import "google/protobuf/timestamp.proto"; +import "xai/api/v1/usage.proto"; // An API service for interaction with image generation models. service Image { @@ -36,6 +36,12 @@ message GenerateImageRequest { // in. See ImageFormat enum for options. ImageFormat format = 11; + // Optional quality setting for image generation. + // Only supported by grok-imagine models. + // Defaults to medium. Some models restrict the accepted values (a request + // outside the model's supported set is rejected). + optional ImageQuality quality = 12; + // Optional aspect ratio for image generation/editing. // Only supported by grok-imagine models. // Defaults to 1:1 if not specified. Auto is only supported for image generation @@ -54,6 +60,62 @@ message GenerateImageRequest { // Each image is either an image URL or a base64-encoded version of the image. // This field cannot be set together with the `image` field. repeated ImageUrlContent images = 17; + + // Optional output storage configuration. When present, the generated + // image(s) are stored in the Files API and a file_id is returned in + // the response alongside the ephemeral URL. + optional StorageOptions storage_options = 19; +} + +// Configuration for storing generation output in the Files API. +message StorageOptions { + // Filename for the stored file. + string filename = 1; + // Seconds from now until the file auto-expires. If omitted, the file + // does not expire. + optional int64 expires_after = 2; + // When present, a public URL is created for the stored file after upload. + // The public URL is accessible without authentication. + // Omit entirely to store the file privately (no public URL). + optional PublicUrlOptions public_url = 3; +} + +// Configuration for creating a public URL alongside file storage. +message PublicUrlOptions { + // Seconds from now until the public URL expires. + // + // If omitted and the file has a TTL (`StorageOptions.expires_after`), + // the public URL inherits the file's expiry. If omitted and the file + // has no TTL, the public URL remains valid indefinitely until the file + // is deleted or the URL is explicitly revoked via `RevokePublicUrl`. + // The file itself always remains accessible via authenticated endpoints + // after the public URL expires. + optional int64 expires_after = 1; +} + +// Information about a generated file stored in the Files API. +message FileOutput { + // Files API file_id of the stored file. + string file_id = 1; + // Filename of the stored file. + string filename = 2; + reserved 3; + // Public URL for the stored file. Only present when the request included + // storage_options.public_url and creation succeeded. + optional string public_url = 4; + // When the public URL expires. Only present when public_url is set and + // has an independent expiry (i.e. the request specified + // public_url.expires_after, or the file has a TTL). Absent when the + // public URL is valid indefinitely. + optional google.protobuf.Timestamp public_url_expires_at = 5; + // When the stored file expires and will be automatically deleted. Only + // present when the file has an expiration (storage_options.expires_after + // was set). + optional google.protobuf.Timestamp expires_at = 6; + // Human-readable error when storage_options.public_url was set but + // public URL creation failed. The file itself was stored successfully — + // the public URL can be retried via `CreatePublicUrl`. + optional string public_url_error = 7; } // The response from the image generation models containing the generated image(s). @@ -87,18 +149,35 @@ message GeneratedImage { // The field will be true if the image respect moderation rules. Otherwise // the field will be false and the image field is replaced by a placeholder. bool respect_moderation = 4; + + // Storage info for the generated image. Only present when the request + // included `storage_options` and the upload succeeded. + optional FileOutput file_output = 8; + + // Human-readable error when `storage_options` was set but the upload + // failed. Only present on storage failure; absent on success or when + // storage was not requested. + optional string storage_error = 9; } // Contains data relating to an image that is provided to the model. message ImageUrlContent { - // This is either an image URL or a base64-encoded version of the image. - // The following image formats are supported: PNG, JPG, and WebP. - // If an image URL is provided, the image will be downloaded for every API - // request without being cached. Images are fetched using - // "XaiImageApiFetch/1.0" user agent, and will timeout after 5 seconds. - // The image size is limited to 10 MiB. If the image download fails, the API - // request will fail as well. - string image_url = 1; + // The source of the image — either a direct URL/base64 string or a + // file_id from the xAI Files API. Exactly one must be set. + oneof source { + // This is either an image URL or a base64-encoded version of the image. + // The following image formats are supported: PNG, JPG, and WebP. + // If an image URL is provided, the image will be downloaded for every API + // request without being cached. Images are fetched using + // "XaiImageApiFetch/1.0" user agent, and will timeout after 5 seconds. + // The image size is limited to 10 MiB. If the image download fails, the API + // request will fail as well. + string image_url = 1; + + // A file ID from the xAI Files API. The file must be an image + // (JPEG, PNG, or WebP). + string file_id = 3; + } // The level of pre-processing resolution that will be applied to the image. ImageDetail detail = 2; diff --git a/src/xAI.Protocol/usage.proto b/src/xAI.Protocol/usage.proto index e0171ac..0599ed1 100644 --- a/src/xAI.Protocol/usage.proto +++ b/src/xAI.Protocol/usage.proto @@ -1,5 +1,4 @@ syntax = "proto3"; -option csharp_namespace = "xAI.Protocol"; package xai_api; @@ -78,4 +77,5 @@ enum ServerSideTool { SERVER_SIDE_TOOL_MCP = 7; SERVER_SIDE_TOOL_ATTACHMENT_SEARCH = 8; SERVER_SIDE_TOOL_IMAGE_SEARCH = 10; + SERVER_SIDE_TOOL_IMAGE_GENERATION = 11; } diff --git a/src/xAI.Protocol/video.proto b/src/xAI.Protocol/video.proto index b12e5be..08df675 100644 --- a/src/xAI.Protocol/video.proto +++ b/src/xAI.Protocol/video.proto @@ -1,11 +1,10 @@ syntax = "proto3"; -option csharp_namespace = "xAI.Protocol"; package xai_api; -import "deferred.proto"; -import "image.proto"; -import "usage.proto"; +import "xai/api/v1/deferred.proto"; +import "xai/api/v1/image.proto"; +import "xai/api/v1/usage.proto"; // Aspect ratio for video generation. enum VideoAspectRatio { @@ -46,13 +45,41 @@ enum VideoResolution { // 720p resolution. // Dimensions vary by aspect ratio VIDEO_RESOLUTION_720P = 2; + + // 1080p resolution. + // Dimensions vary by aspect ratio. + // Supported on models that advertise 1080p (e.g. grok-imagine-video-1.5 for + // image-to-video); not available on all video models. + VIDEO_RESOLUTION_1080P = 3; } -// Specifies a video by URL for video editing. +// Specifies a video by URL or file reference for video editing. message VideoUrlContent { - // Either a URL of the video (e.g., a public URL) or a base64-encoded video - // as a data URL (e.g., "data:video/mp4;base64,..."). - string url = 1; + // The source of the video — either a direct URL/base64 string or a + // file_id from the xAI Files API. Exactly one must be set. + oneof source { + // Either a URL of the video (e.g., a public URL) or a base64-encoded video + // as a data URL (e.g., "data:video/mp4;base64,..."). + string url = 1; + + // A file ID from the xAI Files API. The file must be a video + // (e.g., MP4). + string file_id = 2; + } +} + +// Reference audio input for video generation. +message AudioUrlContent { + reserved 1; + + // The source of the audio. Must be set. + oneof source { + // Identifier of a first-party preset voice (e.g. "ara"), using the same + // voice identifiers as the TTS API. Resolved server-side to a curated + // reference clip from the model's voice-preset catalog. Only supported + // by models that accept reference audio. + string voice_id = 2; + } } // An API service for interaction with video generation models. @@ -111,6 +138,26 @@ message GenerateVideoRequest { // When provided (and `image` is not set), generates video using these images // as style/content references. repeated ImageUrlContent reference_images = 13; + + // Optional output storage configuration. When present, the generated + // video is stored in the Files API and a file_id is returned in + // the response alongside the ephemeral URL. + optional StorageOptions storage_options = 14; + + reserved 15; + + // Optional reference audio (voice identity) for reference-to-video + // generation. Each entry selects a first-party preset voice via + // `voice_id` (same identifiers as the TTS API). Only supported by select + // video models; at most three entries. May be provided without + // reference_images (audio-only reference-to-video) — at least one + // reference of either kind selects the reference-to-video mode. + repeated AudioUrlContent reference_audios = 16; + + // Whether the generated video includes an audio track. Defaults to true. + // Set to false for a silent video (the audio track is stripped + // server-side after generation). + optional bool generate_audio = 17; } // Request for retrieving deferred video generation results. @@ -155,6 +202,15 @@ message GeneratedVideo { // The field will be true if the video respects moderation rules. Otherwise // the field will be false and the video url field will be empty. bool respect_moderation = 5; + + // Storage info for the generated video. Only present when the request + // included `storage_options` and the upload succeeded. + optional FileOutput file_output = 6; + + // Human-readable error when `storage_options` was set but the upload + // failed. Only present on storage failure; absent on success or when + // storage was not requested. + optional string storage_error = 7; } // Response from GetDeferredVideo, including the response if the video @@ -192,4 +248,11 @@ message ExtendVideoRequest { // Duration of the extension segment to generate in seconds (1-10). // Defaults to 6 seconds if not specified. optional int32 duration = 4; + + // Optional output storage configuration. When present, the generated + // video is stored in the Files API and a file_id is returned in + // the response alongside the ephemeral URL. + optional StorageOptions storage_options = 6; + + reserved 7; }