عقد الإجراءات
تعرّف الحزمة adk-action 14 نوعًا من عقد الإجراءات المستخدمة في سير العمل المعتمد على الرسوم البيانية. يمثّل كل نوع من العقدة عملية منفصلة (استدعاء HTTP، تحويل بيانات، فرع شرطي، إلخ) يمكن تركيبها في رسوم بيانية موجهة عبر adk-graph وActionNodeExecutor الخاصة به.
نظرة عامة
تُعد عقد الإجراءات اللبنات الأساسية لرسوم سير العمل المرئية والبرمجية. وهي توفر:
- عمليات ذات أنواع محددة — 14 نوعًا من العقد تغطي أنماط سير العمل الشائعة
- StandardProperties — إعدادات مشتركة لمعالجة الأخطاء، والتتبع، وتعيين البيانات
- استيفاء المتغيرات — صيغة
{{variable}}للقيم الديناميكية - تكامل الرسم البياني — يُنفَّذ بواسطة
adk-graphوActionNodeExecutorالخاصة به
التثبيت
[dependencies]
adk-action = "2.0.0"
# Or specific action features via umbrella crate
adk-rust = { version = "2.0.0", features = ["action"] }
أنواع العقد (14)
| العقدة | الغرض | الفئة |
|---|---|---|
Trigger | نقطة الدخول — تبدأ تنفيذ سير العمل | تحكم |
HTTP | إجراء طلبات HTTP (GET, POST, PUT, DELETE, PATCH) | إدخال/إخراج |
Set | تعيين القيم لمتغيرات سير العمل | البيانات |
Transform | تحويل البيانات باستخدام التعابير أو الشيفرة | البيانات |
Switch | التفرع الشرطي بناءً على التعابير | التحكم |
Loop | التكرار عبر المجموعات أو حتى يتحقق شرط | التحكم |
Merge | دمج عدة فروع مرة أخرى | Control |
Wait | إيقاف التنفيذ مؤقتًا لمدة أو حتى حدث | Control |
Code | تنفيذ تعليمات برمجية عشوائية (Rust; JS/TS غير منفذ) | Compute |
Database | الاستعلام عن قواعد البيانات — غير منفذ | I/O |
Email | إرسال رسائل البريد الإلكتروني عبر SMTP — غير مطبق | I/O |
Notification | إرسال الإشعارات (Slack، webhook، push) | I/O |
RSS | قراءة وتحليل خلاصات RSS/Atom | I/O |
File | قراءة الملفات وكتابتها وتحويلها | I/O |
يتم التحقق من التوافر عند بناء الرسم البياني
تقبل بعض أنواع العقد إعدادًا وتتحقق منه بينما لا توجد واجهتها الخلفية.
يتم رفض هذه الحالات بواسطة StateGraph::compile()، وليس في منتصف التنفيذ:
| التهيئة | الحالة |
|---|---|
Database (any type) | مرفوض — لا يوجد برنامج تشغيل مدمج |
Email (monitor or send) | مرفوض — لم يتم تنفيذ 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
تُنفَّذ عقد الإجراءات بواسطة adk-graph ActionNodeExecutor:
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
- المشغلات — أنواع مشغلات سير العمل
السابق: ← إعادة المحاولة والتأمل | التالي: الإضافات →