عُقد الإجراءات
تعرّف حزمة adk-action 14 نوعًا من عُقد الإجراءات المستخدمة في سير العمل القائم على الرسوم البيانية. يمثّل كل نوع من العُقد عملية منفصلة (استدعاء HTTP، تحويل البيانات، فرع شرطي، وما إلى ذلك) يمكن تركيبها في رسوم بيانية موجّهة عبر ActionNodeExecutor الخاص بـ adk-graph.
نظرة عامة
تُعدّ عُقد الإجراءات اللبنات الأساسية للرسوم البيانية المرئية والبرمجية لسير العمل. وهي توفّر:
- عمليات محددة الأنواع — 14 نوعًا من العُقد تغطي أنماط سير العمل الشائعة
- StandardProperties — إعدادات مشتركة لمعالجة الأخطاء، والتتبّع، وربط البيانات
- استبدال المتغيرات — صيغة
{{variable}}للقيم الديناميكية - التكامل مع الرسم البياني — تُنفَّذ بواسطة
ActionNodeExecutorالخاص بـadk-graph
التثبيت
[dependencies]
adk-action = "2.1.0"
# Or specific action features via umbrella crate
adk-rust = { version = "2.1.0", features = ["action"] }
أنواع العُقد (14)
| العقدة | الغرض | الفئة |
|---|---|---|
Trigger | نقطة الدخول — تبدأ تنفيذ سير العمل | التحكم |
HTTP | إجراء طلبات HTTP (GET، POST، PUT، DELETE، PATCH) | الإدخال/الإخراج |
Set | تعيين قيم لمتغيرات سير العمل | بيانات |
Transform | تحويل البيانات باستخدام التعبيرات أو التعليمات البرمجية | بيانات |
Switch | التفرع الشرطي استنادًا إلى التعبيرات | تحكم |
Loop | التكرار عبر المجموعات أو حتى تحقق شرط | تحكم |
Merge | دمج فروع متعددة معًا | تحكم |
Wait | إيقاف التنفيذ مؤقتًا لمدة محددة أو حتى وقوع حدث | تحكم |
Code | تنفيذ تعليمات برمجية عشوائية (Rust؛ لم يتم تنفيذ JS/TS) | حساب |
Database | الاستعلام عن قواعد البيانات — لم يتم التنفيذ | إدخال/إخراج |
Email | إرسال رسائل البريد الإلكتروني عبر SMTP — غير مُنفَّذ | الإدخال/الإخراج |
Notification | إرسال الإشعارات (Slack، webhook، push) | الإدخال/الإخراج |
RSS | قراءة وتحليل موجزات RSS/Atom | الإدخال/الإخراج |
File | قراءة الملفات وكتابتها وتحويلها | الإدخال/الإخراج |
يتم التحقق من التوفر عند بناء الرسم البياني
تقبل بعض أنواع العقد إعدادًا وتتحقق من صحته، حتى عندما لا تكون الواجهة الخلفية الخاصة بها موجودة.
ترفضها StateGraph::compile()، وليس في منتصف عملية التشغيل:
| الإعداد | الحالة |
|---|---|
Database (أي نوع) | مرفوض — لا يوجد برنامج تشغيل مدمج |
Email (مراقبة أو إرسال) | مرفوض — لم يتم تنفيذ IMAP وSMTP |
Code مع language: javascript أو typescript | مرفوض — لا توجد بيئة تشغيل معزولة؛ استخدم rust |
Http بدون ميزة action-http | مرفوض — فعّل الميزة |
يُسمّي الرفض العقدة والسبب، لذا يفشل سير العمل الذي لا يمكن تشغيله أثناء تجميعه، بدلًا من فشله بعد أن تكون العقد السابقة قد أحدثت آثارًا جانبية بالفعل.
نفّذ Node::validate على عقدة مخصّصة للمشاركة في الفحص نفسه.
StandardProperties
تحمل كل عقدة إجراء StandardProperties — وهي تهيئة مشتركة تتحكم في سلوك التنفيذ:
use adk_action::{StandardProperties, ErrorHandling, RetryConfig};
let props = StandardProperties::builder()
// Error handling
.on_error(ErrorHandling::ContinueOnFail)
.retry(RetryConfig {
max_attempts: 3,
wait_between_ms: 1000,
})
// Tracing
.notes("Fetch user profile from API")
// Callbacks
.on_success("notify_complete")
.on_failure("alert_team")
// Execution
.timeout_ms(30_000)
.continue_on_fail(true)
// Input/output mapping
.input_mapping("{{trigger.body.user_id}}")
.output_key("user_profile")
.build();
StandardProperties الحقول
| الحقل | النوع | الوصف |
|---|---|---|
on_error | ErrorHandling | Stop أو ContinueOnFail أو RetryThenFail |
retry | Option<RetryConfig> | محاولات إعادة المحاولة والتأخير بينها |
notes | Option<String> | وصف قابل للقراءة البشرية للتتبّع |
on_success | Option<String> | عقدة رد الاتصال التي سيتم تنفيذها عند النجاح |
on_failure | Option<String> | عقدة رد الاتصال التي سيتم تنفيذها عند الفشل |
timeout_ms | Option<u64> | الحد الأقصى لوقت التنفيذ |
continue_on_fail | bool | ما إذا كانت العقد اللاحقة تُنفَّذ بعد الفشل |
input_mapping | Option<String> | تعبير لتحويل بيانات الإدخال |
output_key | Option<String> | اسم المتغير لتخزين المخرجات |
استيفاء المتغيرات
تدعم عُقد الإجراءات صيغة {{variable}} للإشارة إلى حالة سير العمل:
use adk_action::HttpNode;
let node = HttpNode::builder()
.url("https://api.example.com/users/{{trigger.body.user_id}}")
.method("GET")
.headers(vec![
("Authorization".into(), "Bearer {{env.API_TOKEN}}".into()),
])
.build();
مصادر المتغيرات
| البادئة | المصدر | المثال |
|---|---|---|
trigger | حمولة عقدة المشغّل | {{trigger.body.email}} |
env | متغيرات البيئة | {{env.DATABASE_URL}} |
nodes | مخرجات العقد السابقة | {{nodes.fetch_user.json.name}} |
workflow | المتغيرات على مستوى سير العمل | {{workflow.run_id}} |
يستخدم الوصول المتداخل تدوين النقاط: {{nodes.http_1.json.data[0].id}}
أمثلة على العُقد
عقدة HTTP
use adk_action::{HttpNode, HttpMethod};
let node = HttpNode::builder()
.method(HttpMethod::Post)
.url("https://api.example.com/orders")
.headers(vec![
("Content-Type".into(), "application/json".into()),
])
.body(r#"{"item": "{{trigger.body.item}}", "qty": {{trigger.body.quantity}}}"#)
.properties(StandardProperties::builder()
.timeout_ms(10_000)
.on_error(ErrorHandling::RetryThenFail)
.retry(RetryConfig { max_attempts: 3, wait_between_ms: 2000 })
.output_key("order_response")
.build())
.build();
عقدة التبديل
use adk_action::{SwitchNode, SwitchCase};
let node = SwitchNode::builder()
.cases(vec![
SwitchCase {
condition: "{{nodes.classify.json.category}} == 'urgent'".into(),
output: "urgent_path".into(),
},
SwitchCase {
condition: "{{nodes.classify.json.category}} == 'normal'".into(),
output: "normal_path".into(),
},
])
.fallback("default_path")
.build();
عقدة التكرار
use adk_action::{LoopNode, LoopMode};
let node = LoopNode::builder()
.mode(LoopMode::ForEach {
items: "{{nodes.fetch_users.json.users}}".into(),
item_var: "current_user".into(),
})
.body_nodes(vec!["process_user", "save_result"])
.properties(StandardProperties::builder()
.notes("Process each user in the list")
.build())
.build();
عقدة التعيين
use adk_action::SetNode;
let node = SetNode::builder()
.assignments(vec![
("status".into(), "processing".into()),
("started_at".into(), "{{workflow.timestamp}}".into()),
("user_email".into(), "{{trigger.body.email}}".into()),
])
.build();
التكامل مع adk-graph
تُنفَّذ عُقد الإجراءات بواسطة ActionNodeExecutor الخاصة بـ adk-graph:
use adk_graph::{Graph, ActionNodeExecutor};
use adk_action::{TriggerNode, HttpNode, SetNode};
// Define nodes
let trigger = TriggerNode::webhook("order_received");
let fetch = HttpNode::get("https://api.example.com/inventory/{{trigger.body.sku}}");
let update = SetNode::new(vec![("available", "{{nodes.fetch.json.quantity}}")]);
// Build graph
let graph = Graph::builder()
.node("trigger", trigger)
.node("check_inventory", fetch)
.node("update_status", update)
.edge("trigger", "check_inventory")
.edge("check_inventory", "update_status")
.build()?;
// Execute
let executor = ActionNodeExecutor::new();
let result = executor.run(graph, initial_context).await?;
تعريف أنواع عُقد مخصّصة
طبّق سمة ActionNode:
use adk_action::{ActionNode, ActionContext, ActionResult, StandardProperties};
use async_trait::async_trait;
struct CustomNode {
config: MyConfig,
properties: StandardProperties,
}
#[async_trait]
impl ActionNode for CustomNode {
fn node_type(&self) -> &str { "custom" }
fn properties(&self) -> &StandardProperties { &self.properties }
async fn execute(&self, ctx: &ActionContext) -> ActionResult {
let input = ctx.resolve("{{trigger.body.data}}")?;
// Custom logic...
Ok(serde_json::json!({ "result": "processed" }))
}
}
ذات صلة
- الوكلاء المعتمدون على الرسوم البيانية — تنسيق سير العمل المعتمد على الرسوم البيانية
- عُقد إجراءات Studio — محرر العُقد المرئي في Studio الخاص بـ ADK
- المشغّلات — أنواع مشغّلات سير العمل
السابق: ← إعادة المحاولة والتأمل | التالي: الإضافات →