mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-05-06 01:32:36 +00:00
feat(flow): support custom persistence key in @persist (#5649)
* feat(flow): add optional key param to @persist decorator Allows users to specify which state attribute to use as the persistence key instead of always defaulting to state.id. Usage: @persist(key='conversation_id') Falls back to state.id when key is not provided (no breaking change). Raises ValueError if the specified key is missing or falsy on state. * docs(flow): document @persist key parameter for custom persistence keys * fix(flow): use explicit None check for persist key to avoid empty-string fallback --------- Co-authored-by: iris-clawd <iris-clawd@anthropic.com> Co-authored-by: iris-clawd <iris@crewai.com> Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
This commit is contained in:
@@ -380,6 +380,33 @@ class AnotherFlow(Flow[dict]):
|
||||
print("Method-level persisted runs:", self.state["runs"])
|
||||
```
|
||||
|
||||
### مفتاح استمرارية مخصص
|
||||
|
||||
افتراضيًا، يستخدم `@persist` الحقل `state.id` المُولّد تلقائيًا كمفتاح للاستمرارية. إذا كان لتدفقك معرّف خاص به — مثل `conversation_id` مشترك بين عدة جلسات — يمكنك تمرير الوسيط `key` ليستخدم `@persist` تلك السمة كـ UUID للتدفق:
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, listen, start
|
||||
from crewai.flow.persistence import persist
|
||||
from pydantic import BaseModel
|
||||
|
||||
class ConversationState(BaseModel):
|
||||
conversation_id: str
|
||||
turn: int = 0
|
||||
|
||||
@persist(key="conversation_id") # استخدام حقل مخصص كمفتاح للاستمرارية
|
||||
class ConversationFlow(Flow[ConversationState]):
|
||||
@start()
|
||||
def begin(self):
|
||||
self.state.turn += 1
|
||||
print(f"Conversation {self.state.conversation_id} turn {self.state.turn}")
|
||||
|
||||
# إعادة تشغيل المحادثة بنفس conversation_id يُعيد تحميل الحالة السابقة
|
||||
flow = ConversationFlow(conversation_id="user-42")
|
||||
flow.kickoff()
|
||||
```
|
||||
|
||||
يقرأ المزخرف القيمة من `state[key]` للحالات من نوع dict، ومن `getattr(state, key)` للحالات من نوع Pydantic / كائن. إذا كانت السمة المحددة غير موجودة أو قيمتها falsy عند الحفظ، يُطلق `@persist` خطأ `ValueError` مثل `Flow state is missing required persistence key 'conversation_id'`. عند حذف `key`، يظل السلوك الأصلي قائمًا ويُستخدم `state.id`.
|
||||
|
||||
### كيف تعمل
|
||||
|
||||
1. **تعريف الحالة الفريد**
|
||||
|
||||
@@ -146,6 +146,15 @@ class ProductionFlow(Flow[AppState]):
|
||||
# ...
|
||||
```
|
||||
|
||||
افتراضيًا، يستخدم `@persist` الحقل `state.id` المُولّد تلقائيًا كمفتاح للحالة المحفوظة. إذا كان تطبيقك يمتلك معرّفًا طبيعيًا بالفعل — مثل `conversation_id` يربط عدة تشغيلات بنفس جلسة المستخدم — مرّره كـ `key` ليستخدمه المزخرف كـ UUID للتدفق. يُطلق `ValueError` إذا كانت السمة المحددة غير موجودة أو قيمتها falsy عند الحفظ.
|
||||
|
||||
```python
|
||||
@persist(key="conversation_id")
|
||||
class ProductionFlow(Flow[AppState]):
|
||||
# يجب أن يحتوي AppState على conversation_id؛ استئناف الجلسة يُعيد تحميل الحالة السابقة
|
||||
...
|
||||
```
|
||||
|
||||
## الخلاصة
|
||||
|
||||
- **ابدأ بتدفق.**
|
||||
|
||||
@@ -116,6 +116,33 @@ class PersistentCounterFlow(Flow[CounterState]):
|
||||
return self.state.value
|
||||
```
|
||||
|
||||
### استخدام مفتاح استمرارية مخصص
|
||||
|
||||
افتراضيًا، يستخدم `@persist()` الحقل `state.id` المُولّد تلقائيًا كمفتاح للحالة المحفوظة. عندما يكون لمجالك معرّف طبيعي بالفعل — مثل `conversation_id` يربط عدة تشغيلات للتدفق بنفس جلسة المستخدم — مرّره كوسيط `key` ليستخدمه `@persist` كـ UUID للتدفق بدلًا من `id`:
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, listen, start
|
||||
from crewai.flow.persistence import persist
|
||||
from pydantic import BaseModel
|
||||
|
||||
class ConversationState(BaseModel):
|
||||
conversation_id: str
|
||||
history: list[str] = []
|
||||
|
||||
@persist(key="conversation_id")
|
||||
class ConversationFlow(Flow[ConversationState]):
|
||||
@start()
|
||||
def greet(self):
|
||||
self.state.history.append("hello")
|
||||
return self.state.history
|
||||
|
||||
# تشغيل ثانٍ بنفس conversation_id يُعيد تحميل الحالة السابقة
|
||||
flow = ConversationFlow(conversation_id="user-42")
|
||||
flow.kickoff()
|
||||
```
|
||||
|
||||
بالنسبة للحالات من نوع dict يقرأ `@persist` القيمة من `state[key]`، ولحالات Pydantic / الكائنات يقرأها من `getattr(state, key)`. إذا كانت السمة المحددة غير موجودة أو قيمتها falsy عند حفظ الحالة، يُطلق `@persist` خطأ `ValueError` مثل `Flow state is missing required persistence key 'conversation_id'`، فيظهر الفشل فورًا بدلًا من فقد بيانات الاستمرارية بصمت. استدعاء `@persist()` بدون `key` يحافظ على السلوك الأصلي ويستخدم `state.id`.
|
||||
|
||||
## أنماط حالة متقدمة
|
||||
|
||||
### المنطق الشرطي المبني على الحالة
|
||||
|
||||
Reference in New Issue
Block a user