مزودو النماذج (السحابة)

ADK-Rust يدعم عدة مزودي LLM سحابية من خلال crate adk-model. ينفذ جميع المزودين الصفة Llm، مما يجعلهم قابلين للتبديل داخل وكلائك.

نظرة عامة

┌─────────────────────────────────────────────────────────────────────┐
│                     Cloud Model Providers                           │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   • Gemini (Google)    ⭐ Default    - Multimodal, large context    │
│   • OpenAI (GPT-5)    🔥 Popular    - Best ecosystem               │
│   • Anthropic (Claude) 🧠 Smart      - Best reasoning               │
│   • DeepSeek           💭 Thinking   - Chain-of-thought, cheap      │
│   • Groq               ⚡ Ultra-Fast  - Fastest inference           │
│                                                                     │
│   For local/offline models, see:                                    │
│   • Ollama     → ollama.md                                          │
│   • mistral.rs → mistralrs.md                                       │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

مقارنة سريعة

الموفرالأفضل لـالسرعةالتكلفةالميزة الرئيسية
Geminiالاستخدام العام⚡⚡⚡💰متعدد الوسائط، سياق كبير، التفكير
OpenAIالموثوقية⚡⚡💰💰أفضل نظام بيئي
Anthropicاستدلال معقد⚡⚡💰💰الأكثر أمانًا والأكثر تفكيرًا
DeepSeekسلسلة الأفكار⚡⚡💰وضع التفكير، منخفض التكلفة
Groqحساسة للسرعة⚡⚡⚡⚡💰أسرع استدلال

الخطوة 1: التثبيت

أضف المزوّدين الذين تحتاجهم إلى Cargo.toml:

[dependencies]
# Pick one or more providers:
adk-model = { version = "2.0.0", features = ["gemini"] }        # Google Gemini (default)
adk-model = { version = "2.0.0", features = ["openai"] }        # OpenAI GPT-5
adk-model = { version = "2.0.0", features = ["anthropic"] }     # Anthropic Claude
adk-model = { version = "2.0.0", features = ["deepseek"] }      # DeepSeek
adk-model = { version = "2.0.0", features = ["groq"] }          # Groq (ultra-fast)

# Or all cloud providers at once:
adk-model = { version = "2.0.0", features = ["all-providers"] }

الخطوة 2: تعيين مفتاح API الخاص بك

export GOOGLE_API_KEY="your-key"      # Gemini
export OPENAI_API_KEY="your-key"      # OpenAI
export ANTHROPIC_API_KEY="your-key"   # Anthropic
export DEEPSEEK_API_KEY="your-key"    # DeepSeek
export GROQ_API_KEY="your-key"        # Groq

تسوية المخطط

يقوم كل مزوّد تلقائيًا بتسوية مخططات الأدوات الخاصة بـ MCP عند وقت الطلب. لا تحتاج إلى فعل أي شيء — فهو يعمل بشفافية. ولكن إليك ما يحدث في الخلفية:

المزوّدمحول المخططالسلوك
GeminiGeminiSchemaAdapterعدواني: يحل $ref، يدمج المجمعات، ويزيل الكلمات المفتاحية غير المدعومة
OpenAI (صارم)OpenAiStrictSchemaAdapterيحافظ على البنية، ويضيف additionalProperties: false
OpenAIOpenAiSchemaAdapterإصلاحات آمنة دنيا
AnthropicAnthropicSchemaAdapterمرور شبه مباشر
DeepSeekGenericSchemaAdapterتحويلات آمنة محافظة
OllamaGenericSchemaAdapterتحويلات آمنة محافظة

يمكنك الوصول إلى المكيّف برمجيًا عبر الـ Llm:

use adk_core::{Llm, SchemaAdapter};

let adapter = model.schema_adapter();
let normalized = adapter.normalize_schema(raw_schema);

راجع Schema Normalization للحصول على التوثيق الكامل.


Gemini (Google) ⭐ الافتراضي

الأفضل لـ: المهام العامة، والمهام متعددة الوسائط، والمستندات الكبيرة

أبرز الميزات:

  • 🖼️ وسائط متعددة أصلية (صور، فيديو، صوت، PDF)
  • 📚 نافذة سياق تصل إلى 2M رمز
  • 🧠 وضع التفكير: قائم على المستويات (Gemini 3) وقائم على الميزانية (Gemini 2.5) مع توقيعات التفكير
  • 💰 تسعير تنافسي
  • ⚡ استدلال سريع

مثال عملي كامل

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv().ok();
    
    let api_key = std::env::var("GOOGLE_API_KEY")?;
    let model = GeminiModel::new(&api_key, "gemini-2.5-flash")?;

    let agent = LlmAgentBuilder::new("gemini_assistant")
        .description("Gemini-powered assistant")
        .instruction("You are a helpful assistant powered by Google Gemini. Be concise.")
        .model(Arc::new(model))
        .build()?;

    Launcher::new(Arc::new(agent)).run().await?;
    Ok(())
}

النماذج المتاحة

النموذجالوصفالسياق
gemini-3.1-pro-previewأقوى استدلال لعمليات سير العمل المعقدة متعددة الوكلاء2 مليون رمز
gemini-3-flash-previewسريع وفعّال للبرمجة والوكلاء1 مليون رمز
gemini-3.1-flash-lite-previewالتوجيه الأرخص والأسرع والمهام عالية الحجم1M tokens
gemini-2.5-proالاستدلال المتقدم ومتعدد الوسائط1M tokens
gemini-2.5-flashتوازن بين السرعة والقدرة (موصى به)1M tokens

وضع التفكير

تدعم نماذج Gemini 3 التفكير القائم على المستوى، بينما يستخدم Gemini 2.5 التفكير القائم على الميزانية. عند استخدام وضع التفكير مع استدعاء الدوال، تُرجع نماذج Gemini 2.5+ و3.x قيم thoughtSignature يجب إعادة إرسالها في الجولات اللاحقة للحفاظ على سياق الاستدلال. يتعامل ADK-Rust مع هذا تلقائيًا — تُسلسَل التواقيع عند وجودها وتُحذف عند None.

use adk_gemini::{Gemini, ThinkingLevel};

// Gemini 3: level-based thinking
let response = client.generate_content()
    .with_user_message("Solve this step by step")
    .with_thinking_level(ThinkingLevel::High)
    .with_thoughts_included(true)
    .execute().await?;

// Gemini 2.5: budget-based thinking
let response = client.generate_content()
    .with_user_message("Solve this step by step")
    .with_thinking_budget(2048)
    .with_thoughts_included(true)
    .execute().await?;

مثال الإخراج

👤 User: What's in this image? [uploads photo of a cat]

🤖 Gemini: I can see a fluffy orange tabby cat sitting on a windowsill. 
The cat appears to be looking outside, with sunlight illuminating its fur. 
It has green eyes and distinctive striped markings typical of tabby cats.

الأفضل لـ: تطبيقات الإنتاج، أداء موثوق، قدرات واسعة

أبرز النقاط:

  • 🏆 المعيار الصناعي
  • 🔧 استدعاء أدوات/دوال ممتاز
  • 📖 أفضل توثيق ونظام بيئي
  • 🎯 مخرجات متسقة ومتوقعة
  • 📋 مخرجات منظمة مع فرض مخطط JSON
  • 🧠 التحكم في جهد الاستدلال لنماذج الاستدلال o1/o3
  • 🆕 Responses API — عميل مخصص لـ /v1/responses مع ملخصات الاستدلال، وأدوات مدمجة، وحالة على جانب الخادم

مثال عملي كامل

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv().ok();
    
    let api_key = std::env::var("OPENAI_API_KEY")?;
    let model = OpenAIClient::new(OpenAIConfig::new(&api_key, "gpt-5-mini"))?;

    let agent = LlmAgentBuilder::new("openai_assistant")
        .description("OpenAI-powered assistant")
        .instruction("You are a helpful assistant powered by OpenAI GPT-5. Be concise.")
        .model(Arc::new(model))
        .build()?;

    Launcher::new(Arc::new(agent)).run().await?;
    Ok(())
}

المخرجات المنظمة (مخطط JSON)

يدعم OpenAI مخرجات JSON مضمونة عبر output_schema. يربط ADK-Rust هذا تلقائيًا مع مخطط OpenAI response_format API:

use adk_rust::prelude::*;
use serde_json::json;
use std::sync::Arc;

let model = OpenAIClient::new(OpenAIConfig::new(&api_key, "gpt-5-mini"))?;

let agent = LlmAgentBuilder::new("data_extractor")
    .model(Arc::new(model))
    .instruction("Extract person information from the text.")
    .output_schema(json!({
        "type": "object",
        "properties": {
            "name": { "type": "string" },
            "age": { "type": "number" },
            "email": { "type": "string" }
        },
        "required": ["name", "age"]
    }))
    .build()?;

// Response is guaranteed to be valid JSON matching the schema

للوضع الصارم مع الكائنات المتداخلة، أضف additionalProperties: false في كل مستوى:

.output_schema(json!({
    "type": "object",
    "properties": {
        "title": { "type": "string" },
        "metadata": {
            "type": "object",
            "properties": {
                "author": { "type": "string" },
                "tags": { "type": "array", "items": { "type": "string" } }
            },
            "required": ["author"],
            "additionalProperties": false  // Required for nested objects
        }
    },
    "required": ["title", "metadata"],
    "additionalProperties": false  // Auto-injected at root level
}))

جهد الاستدلال (نماذج o1, o3)

لنماذج الاستدلال OpenAI، تحكم في مقدار جهد الاستدلال الذي يطبقه النموذج:

use adk_model::openai::{OpenAIClient, OpenAIConfig, ReasoningEffort};

let config = OpenAIConfig::new(&api_key, "o3-mini")
    .with_reasoning_effort(ReasoningEffort::High);
let model = OpenAIClient::new(config)?;

المستويات المتاحة: Low، Medium، High. يؤدي الجهد الأعلى إلى استدلال أكثر شمولًا على حساب زمن الاستجابة والرموز.

OpenAI-متوافق مع APIs المحلي

استخدم OpenAIConfig::compatible() للاتصال بالخوادم المحلية (Ollama، vLLM، LM Studio):

// Ollama exposes OpenAI-compatible API at /v1
let config = OpenAIConfig::compatible(
    "not-needed",                      // API key (ignored by Ollama)
    "http://localhost:11434/v1",       // Base URL
    "llama3.2"                         // Model name
);
let model = OpenAIClient::new(config)?;

ملاحظة: يتطلب المخرج المنظم (output_schema) دعمًا من الواجهة الخلفية. يدعمه OpenAI الأصلي بالكامل؛ وقد تكون دعم الخوادم المحلية محدودًا.

Gemini عبر نقطة النهاية المتوافقة مع OpenAI

يمكن الوصول إلى نماذج Gemini عبر تنسيق Chat Completions السلكي الخاص بـ OpenAI على https://generativelanguage.googleapis.com/v1beta/openai. استخدم الإعداد المسبق OpenAICompatibleConfig::gemini(...) (ضمن ميزة openai) مع GEMINI_API_KEY لتشغيل Gemini عبر نفس العميل المتوافق مع OpenAI الذي تستخدمه مع كل مزود آخر:

use adk_model::openai_compatible::{OpenAICompatible, OpenAICompatibleConfig};

let api_key = std::env::var("GEMINI_API_KEY")?;
let model = OpenAICompatible::new(
    OpenAICompatibleConfig::gemini(api_key, "gemini-3.5-flash"),
)?;

يدعم هذا المسار الدردشة، والبث، واستدعاء الدوال، والمخرجات المنظمة، و جهد الاستدلال (تُطابق OpenAI's reasoning_effort مستويات/ميزانيات التفكير في Gemini). تُمرَّر خيارات Gemini الخاصة — مثل thinking_config مع include_thoughts، أو cached_content — عبر خريطة extensions["openai"]["extra_body"]["google"] الخاصة بالطلب، والتي يدمجها العميل كما هي حرفيًا في جسم الطلب.

متى تستخدم هذا بدلًا من GeminiModel: لميزات Gemini الأصلية (الأدوات على جانب الخادم، واجهة Interactions API، ThinkingConfig الأصلية، والبيئة متعددة الوسائط أولًا)، يُفضَّل GeminiModel. استخدم الإعداد المسبق المتوافق مع OpenAI عندما تريد عميلًا موحدًا واحدًا عبر جميع المزودين.

أمثلة (تتطلب GEMINI_API_KEY أو GOOGLE_API_KEY):

# Direct client: chat, reasoning effort, extra_body thinking, streaming,
# function calling, structured output.
cargo run -p adk-model --features openai --example gemini_openai_compat

# The same compat client driving a normal LlmAgent in a Runner.
# (Lives in adk-agent: it exercises the agent layer, which sits above adk-model.)
cargo run -p adk-agent --example gemini_openai_compat_agent

جهد الاستدلال (نماذج o1, o3)

تحكم في مقدار جهد الاستدلال الذي يطبقه النموذج باستخدام ReasoningEffort:

use adk_model::openai::{OpenAIClient, OpenAIConfig, ReasoningEffort};

let config = OpenAIConfig::new(&api_key, "o3-mini")
    .with_reasoning_effort(ReasoningEffort::High);
let model = OpenAIClient::new(config)?;

المستويات المتاحة: Low (الأسرع)، Medium (متوازن)، High (الأكثر شمولًا).

النماذج المتاحة

النموذجالوصفالسياق
gpt-5نموذج موحّد متطور مع تفكير تكيفي256K رمزًا
gpt-5-miniنسخة فعّالة لمعظم المهام (موصى بها)128K رمزًا
gpt-5-nanoالتوجيه والتصنيف الأقل تكلفة128 ألف رمز
gpt-4.1نموذج إنتاج مستقر لنشر GPT-4.1 القديم1 مليون رمز

مثال على الإخراج

👤 User: Write a haiku about Rust programming

🤖 GPT-5: Memory so safe,
Ownership guards every byte—
Compiler, my friend.

أنثروبيك (Claude) 🧠 ذكي

الأفضل لـ: الاستدلال المعقد، التطبيقات الحساسة للسلامة، المستندات الطويلة

أبرز النقاط:

  • 🧠 قدرة استدلال استثنائية
  • 🛡️ الأكثر تركيزًا على السلامة
  • 📚 سياق 200K token
  • ✍️ جودة كتابة ممتازة

مثال عملي كامل

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv().ok();
    
    let api_key = std::env::var("ANTHROPIC_API_KEY")?;
    let model = AnthropicClient::new(AnthropicConfig::new(&api_key, "claude-sonnet-4-6"))?;

    let agent = LlmAgentBuilder::new("anthropic_assistant")
        .description("Anthropic-powered assistant")
        .instruction("You are a helpful assistant powered by Anthropic Claude. Be concise and thoughtful.")
        .model(Arc::new(model))
        .build()?;

    Launcher::new(Arc::new(agent)).run().await?;
    Ok(())
}

النماذج المتاحة

النموذجالوصفالسياق
claude-opus-4-7الأكثر قدرة GA نموذج، تفكير تكيفي فقط1M tokens
claude-opus-4-6الرائد السابق للمهام المستقلة المعقدة1M tokens
claude-sonnet-4-6توازن بين الذكاء والتكلفة (موصى به)1M رموز
claude-haiku-4-5-20251001عالي الكفاءة لأحمال العمل ذات الحجم الكبير200K رمزًا
claude-opus-4-20250514نموذج هجين مع تفكير ممتد200K رمزًا
claude-sonnet-4-20250514نموذج متوازن مع تفكير ممتد1M رموز

مثال الإخراج

👤 User: Explain quantum entanglement to a 10-year-old

🤖 Claude: Imagine you have two magic coins. When you flip them, they always 
land the same way - both heads or both tails - even if one coin is on Earth 
and the other is on the Moon! Scientists call this "entanglement." The coins 
are connected in a special way that we can't see, like invisible best friends 
who always make the same choice at the exact same time.

DeepSeek 💭 التفكير

الأفضل لـ: حل المشكلات المعقدة، الرياضيات، البرمجة، ومهام الاستدلال

أهم المزايا:

  • 💭 وضع التفكير - يعرض سلسلة التفكير المنطقي
  • 💰 فعّال جدًا من حيث التكلفة (أرخص 10 مرات من GPT-4)
  • 🔄 تخزين السياق مؤقتًا للبادئات المتكررة
  • 🧮 قوي في الرياضيات والبرمجة

مثال عمل كامل

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv().ok();
    
    let api_key = std::env::var("DEEPSEEK_API_KEY")?;
    
    // Standard chat model
    let model = DeepSeekClient::chat(&api_key)?;
    
    // OR: Reasoning model with thinking mode
    // let model = DeepSeekClient::reasoner(&api_key)?;

    let agent = LlmAgentBuilder::new("deepseek_assistant")
        .description("DeepSeek-powered assistant")
        .instruction("You are a helpful assistant powered by DeepSeek. Be concise.")
        .model(Arc::new(model))
        .build()?;

    Launcher::new(Arc::new(agent)).run().await?;
    Ok(())
}

النماذج المتاحة

النموذجالوصفالميزة الخاصة
deepseek-r1-0528أحدث نموذج للاستدلالعمق تفكير محسّن
deepseek-r1استدلال متقدممماثل لـ o1
deepseek-v3.1أحدث نموذج 671B MoEمهام عامة
deepseek-chatنموذج 671B MoE (V3)عام، منخفض التكلفة
deepseek-vl2نموذج رؤية-لغةمتعدد الوسائط

مثال للإخراج (المستدعي مع وضع التفكير)

👤 User: What's 17 × 23?

🤖 DeepSeek: <thinking>
Let me break this down:
17 × 23 = 17 × (20 + 3)
       = 17 × 20 + 17 × 3
       = 340 + 51
       = 391
</thinking>

The answer is 391.

Groq ⚡ فائق السرعة

الأفضل لـ: التطبيقات في الوقت الفعلي، روبوتات الدردشة، المهام الحساسة للسرعة

أبرز المميزات:

  • أسرع استدلال - أسرع 10 مرات من المنافسين
  • 🔧 تقنية LPU (وحدة معالجة اللغة)
  • 💰 تسعير تنافسي
  • 🦙 يشغّل نماذج LLaMA وMixtral وGemma

مثال عملي كامل

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenvy::dotenv().ok();
    
    let api_key = std::env::var("GROQ_API_KEY")?;
    let model = GroqClient::llama70b(&api_key)?;

    let agent = LlmAgentBuilder::new("groq_assistant")
        .description("Groq-powered assistant")
        .instruction("You are a helpful assistant powered by Groq. Be concise and fast.")
        .model(Arc::new(model))
        .build()?;

    Launcher::new(Arc::new(agent)).run().await?;
    Ok(())
}

النماذج المتاحة

النموذجالطريقةالوصف
llama-4-scoutGroqClient::new(GroqConfig::new(key, "llama-4-scout"))Llama 4 Scout (17Bx16E)
llama-3.2-90b-text-previewGroqClient::new(GroqConfig::new(key, "llama-3.2-90b-text-preview"))نموذج نصي كبير
llama-3.1-70b-versatileGroqClient::llama70b()نموذج كبير متعدد الاستخدامات
llama-3.1-8b-instantGroqClient::llama8b()الأسرع
mixtral-8x7b-32768GroqClient::mixtral()توازن جيد
أي نموذجGroqClient::new(GroqConfig::new(key, "model"))نموذج مخصص

مثال الإخراج

👤 User: Quick! Name 5 programming languages

🤖 Groq (in 0.2 seconds): 
1. Rust
2. Python
3. JavaScript
4. Go
5. TypeScript

تبديل المزوّدين

تُنفّذ جميع المزوّدين نفس الصفة Llm، لذا فإن التبديل سهل:

use adk_agent::LlmAgentBuilder;
use std::sync::Arc;

// Just change the model - everything else stays the same!
let model: Arc<dyn adk_core::Llm> = Arc::new(
    // Pick one:
    // GeminiModel::new(&api_key, "gemini-2.5-flash")?
    // OpenAIClient::new(OpenAIConfig::new(&api_key, "gpt-5-mini"))?
    // AnthropicClient::new(AnthropicConfig::new(&api_key, "claude-sonnet-4-6"))?
    // DeepSeekClient::chat(&api_key)?
    // GroqClient::llama70b(&api_key)?
);

let agent = LlmAgentBuilder::new("assistant")
    .instruction("You are a helpful assistant.")
    .model(model)
    .build()?;

أمثلة

استخدم cargo-adk لإنشاء مشاريع خاصة بكل مزوّد مع تبعيات 0.8 مُتحقَّق منها:

cargo adk new gemini_agent --provider gemini
cargo adk new openai_agent --template openai
cargo adk new anthropic_agent --provider anthropic

يتم تجميع المشاريع المُنشأة في CI بواسطة scripts/check-cargo-adk-templates.sh. يمكنك تصفح معرض الأمثلة الكامل وتشغيله في ADK-Rust Playground المضمّن.



السابق: ← الوكلاء الفوريون | التالي: Ollama (محلي) →

ما الذي يحدث للمحتوى الذي لا يستطيع المزوّد حمله

يمكن لـ Content التعبير عن أكثر مما يقبله أي نقل لمزوّد واحد، لذا على كل مُكيِّف أن يقرر ما الذي سيفعله بالباقي. تُسجَّل هذه القرارات الآن بدلًا من تطبيقها بشكل غير مرئي. يُصنَّف كل جزء:

التصرفالمعنى
Convertedيُنقل إلى المزوّد بصيغة أصلية مكافئة
Downgradedيُنقل بصيغة أكثر فقدانًا — مرجع ملف مُقدَّم كنص وصفي يمكن للنموذج قراءته لكنه لا يستطيع جلبه
Omittedغير منقول على الإطلاق

عمليات الخفض والحذف تُصدِر تحذير tracing عند تسجيلها، مع تسمية نوع الجزء ونوع MIME والسبب، بحيث لا يمرّ أيٌّ منهما بصمت.

لرؤية النتيجة قبل إرسال طلب:

use adk_core::{Content, Part};
use adk_model::bedrock::convert::report_for_contents;

let content = Content {
    role: "user".to_string(),
    parts: vec![Part::inline_data("audio/wav", vec![0u8; 16])],
};
let report = report_for_contents(std::slice::from_ref(&content));

for omission in report.omitted_parts() {
    println!("{} was dropped: {}", omission.kind, omission.detail);
}

لرفض طلبٍ سيصل إلى النموذج بشكل غير كامل بدلًا من تلقي إجابة عن مادة لم يرها النموذج مطلقًا:

use adk_core::{Content, Part};
use adk_model::bedrock::convert::report_for_contents;

let content = Content {
    role: "user".to_string(),
    parts: vec![Part::inline_data("video/mp4", vec![0u8; 16])],
};

if let Some(error) = report_for_contents(std::slice::from_ref(&content)).into_error() {
    return Err(error);
}

into_error يغطي الحذف فقط. أمّا الخفض فسيصل إلى النموذج على أي حال، ورفضه سيرفض البديل النصي الموثق.

ملاحظة: السجلّ كاملٌ بحكم البناء. أي جزء يغادر أداةً تكييفية دون مصيرٍ مسجّل — بما في ذلك ما يُضاف بتغيير مستقبلي — يُسجَّل على أنه حذف مع "لا سبب مسجل" صريح، وadk-model/tests/part_conversion_matrix_tests.rs يفشل عليه.

تغطية Bedrock Converse

الجزءالحالة
نص، FunctionCall، FunctionResponse، تفكيرConverted
InlineData مع JPEG، PNG، GIF، WebPConverted ككتلة صورة
InlineData مع نوع مستند مدعوم (PDF وما شابهها)Converted ككتلة مستند
InlineData مع الصوت أو الفيديو أو أي بيانات ثنائية عشوائيةOmitted
FileData لصورة أو مستند مدعومDowngraded إلى نص — يستقبل Converse ‏S3 URIs، وليس URLs عشوائية
FileData لأي نوع آخرOmitted
ServerToolCall، ServerToolResponseOmitted — خاص بـ Gemini
EmbeddedResource نص، أو كائن ثنائي من نوع مدعومConverted
كائن ثنائي من نوع غير مدعوم EmbeddedResourceOmitted