Get started
ACP जीवनचक्र रिफैक्टर
ACP जीवनचक्र अभी काम करता है, लेकिन इसका बहुत अधिक हिस्सा बाद में अनुमानित किया जाता है।
प्रक्रिया सफाई PIDs, कमांड स्ट्रिंग, रैपर
पथ, और लाइव प्रक्रिया तालिका से स्वामित्व को फिर से बनाती है। सत्र दृश्यता
सत्र-कुंजी स्ट्रिंग और द्वितीयक sessions.list({ spawnedBy }) लुकअप से स्वामित्व को फिर से बनाती है।
इससे संकीर्ण सुधार संभव होते हैं, लेकिन किनारी मामलों को चूकना भी आसान हो जाता है:
PID पुन: उपयोग, उद्धृत कमांड, एडाप्टर ग्रैंडचिल्ड्रेन, बहु-Gateway स्थिति रूट,
cancel बनाम close, और tree बनाम all दृश्यता सभी समान स्वामित्व नियमों को
फिर से खोजने के अलग-अलग स्थान बन जाते हैं।
यह रिफैक्टर स्वामित्व को प्रथम-श्रेणी बनाता है। लक्ष्य कोई नया ACP उत्पाद सतह नहीं है; यह मौजूदा ACP और ACPX व्यवहार के लिए एक अधिक सुरक्षित आंतरिक अनुबंध है।
लक्ष्य
- सफाई कभी भी किसी प्रक्रिया को सिग्नल नहीं भेजती जब तक कि वर्तमान लाइव साक्ष्य OpenClaw-स्वामित्व वाली लीज़ से मेल न खाए।
cancel,close, और स्टार्टअप रीपिंग के अलग-अलग जीवनचक्र इरादे होते हैं।sessions_list,sessions_history,sessions_send, और स्थिति जांच समान अनुरोधकर्ता-स्वामित्व वाले सत्र मॉडल का उपयोग करते हैं।- बहु-Gateway इंस्टॉल एक-दूसरे के ACPX रैपर रीप नहीं कर सकते।
- पुराने ACPX सत्र रिकॉर्ड माइग्रेशन के दौरान काम करते रहते हैं।
- रनटाइम Plugin-स्वामित्व वाला रहता है; कोर ACPX पैकेज विवरण नहीं सीखता।
गैर-लक्ष्य
- ACPX को बदलना या सार्वजनिक
/acpकमांड सतह बदलना। - विक्रेता-विशिष्ट ACP एडाप्टर व्यवहार को कोर में ले जाना।
- उपयोगकर्ताओं से अपग्रेड से पहले स्थिति को मैन्युअल रूप से साफ करवाना।
cancelको पुन: उपयोग योग्य ACP सत्र बंद करवाना।
लक्षित मॉडल
Gateway इंस्टेंस पहचान
हर Gateway प्रक्रिया के पास एक स्थिर रनटाइम इंस्टेंस आईडी होनी चाहिए:
type GatewayInstanceId = string;इसे Gateway स्टार्टअप पर जनरेट किया जा सकता है और उस इंस्टॉल के जीवनकाल के लिए स्थिति में स्थायी रखा जा सकता है। यह कोई सुरक्षा रहस्य नहीं है; यह एक स्वामित्व विभेदक है, जिसका उपयोग एक Gateway की ACP प्रक्रियाओं को दूसरे Gateway की प्रक्रियाओं से भ्रमित होने से बचाने के लिए किया जाता है।
ACP सत्र स्वामित्व
हर शुरू किए गए ACP सत्र के पास सामान्यीकृत स्वामित्व मेटाडेटा होना चाहिए:
type AcpSessionOwner = { sessionKey: string; spawnedBy?: string; parentSessionKey?: string; ownerSessionKey: string; agentId: string; backend: "acpx"; gatewayInstanceId: GatewayInstanceId; createdAt: number;};Gateway को ये फ़ील्ड उन सत्र पंक्तियों पर लौटाने चाहिए जहां वे ज्ञात हों। दृश्यता फ़िल्टरिंग पंक्ति मेटाडेटा पर एक शुद्ध जांच होनी चाहिए:
canSeeSessionRow({ row, requesterSessionKey, visibility, a2aPolicy,});यह दृश्यता जांचों से छिपे हुए द्वितीयक sessions.list({ spawnedBy }) कॉल हटाता है।
एक शुरू किया गया क्रॉस-एजेंट ACP चाइल्ड अनुरोधकर्ता-स्वामित्व वाला है क्योंकि
पंक्ति ऐसा कहती है, न कि इसलिए कि कोई दूसरी क्वेरी संयोग से उसे खोज लेती है।
ACPX प्रक्रिया लीज़
हर जनरेट किए गए रैपर लॉन्च को एक लीज़ रिकॉर्ड बनाना चाहिए:
type AcpxProcessLease = { leaseId: string; gatewayInstanceId: GatewayInstanceId; sessionKey: string; wrapperRoot: string; wrapperPath: string; rootPid: number; processGroupId?: number; commandHash: string; startedAt: number; state: "open" | "closing" | "closed" | "lost";};रैपर प्रक्रिया को अपने वातावरण में लीज़ आईडी और Gateway इंस्टेंस आईडी प्राप्त होनी चाहिए:
OPENCLAW_ACPX_LEASE_ID=...OPENCLAW_GATEWAY_INSTANCE_ID=...जब प्लेटफ़ॉर्म अनुमति देता है, सत्यापन को लाइव प्रक्रिया मेटाडेटा को प्राथमिकता देनी चाहिए जिसे कमांड उद्धरण से भ्रमित नहीं किया जा सकता:
- रूट PID अभी भी मौजूद है
- लाइव रैपर पथ
wrapperRootके अंतर्गत है - उपलब्ध होने पर प्रक्रिया समूह लीज़ से मेल खाता है
- पढ़े जाने योग्य होने पर वातावरण में अपेक्षित लीज़ आईडी है
- कमांड हैश या निष्पादन योग्य पथ लीज़ से मेल खाता है
यदि लाइव प्रक्रिया सत्यापित नहीं की जा सकती, तो सफाई फेल-क्लोज़्ड होती है।
जीवनचक्र नियंत्रक
एक ACPX जीवनचक्र नियंत्रक पेश करें जो प्रक्रिया लीज़ और सफाई नीति का स्वामी हो:
interface AcpxLifecycleController { ensureSession(input: AcpRuntimeEnsureInput): Promise<AcpRuntimeHandle>; cancelTurn(handle: AcpRuntimeHandle): Promise<void>; closeSession(input: { handle: AcpRuntimeHandle; discardPersistentState?: boolean; reason?: string; }): Promise<void>; reapStartupOrphans(): Promise<void>; verifyOwnedTree(lease: AcpxProcessLease): Promise<OwnedProcessTree | null>;}cancelTurn केवल टर्न रद्द करने का अनुरोध करता है। उसे पुन: उपयोग योग्य रैपर
या एडाप्टर प्रक्रियाओं को रीप नहीं करना चाहिए।
closeSession को रीप करने की अनुमति है, लेकिन केवल सत्र रिकॉर्ड लोड करने,
लीज़ लोड करने, और यह सत्यापित करने के बाद कि लाइव प्रक्रिया वृक्ष अभी भी उस
लीज़ का है।
reapStartupOrphans स्थिति में मौजूद खुली लीज़ से शुरू करता है। वह वंशज खोजने के लिए
प्रक्रिया तालिका का उपयोग कर सकता है, लेकिन उसे पहले मनमाने ACP-जैसे कमांड स्कैन करके
फिर यह तय नहीं करना चाहिए कि वे शायद हमारे हैं।
रैपर अनुबंध
जनरेट किए गए रैपर छोटे रहने चाहिए। उन्हें:
- समर्थित होने पर एडाप्टर को प्रक्रिया समूह में शुरू करना चाहिए
- सामान्य समाप्ति सिग्नल प्रक्रिया समूह को अग्रेषित करने चाहिए
- पैरेंट की मृत्यु पहचाननी चाहिए
- पैरेंट की मृत्यु पर SIGTERM भेजना चाहिए, फिर SIGKILL फ़ॉलबैक चलने तक रैपर को जीवित रखना चाहिए
- उपलब्ध होने पर रूट PID और प्रक्रिया समूह आईडी को जीवनचक्र नियंत्रक को वापस रिपोर्ट करना चाहिए
रैपरों को सत्र नीति तय नहीं करनी चाहिए। वे केवल अपने एडाप्टर समूह के लिए स्थानीय प्रक्रिया-वृक्ष सफाई लागू करते हैं।
सत्र दृश्यता अनुबंध
दृश्यता को सामान्यीकृत पंक्ति स्वामित्व का उपयोग करना चाहिए:
type SessionVisibilityInput = { requesterSessionKey: string; row: { key: string; agentId: string; ownerSessionKey?: string; spawnedBy?: string; parentSessionKey?: string; }; visibility: "self" | "tree" | "agent" | "all"; a2aPolicy: AgentToAgentPolicy;};नियम:
self: केवल अनुरोधकर्ता सत्र।tree: अनुरोधकर्ता सत्र और अनुरोधकर्ता द्वारा स्वामित्व वाली या उससे शुरू की गई पंक्तियां।all: सभी समान-एजेंट पंक्तियां, a2a-अनुमत क्रॉस-एजेंट पंक्तियां, और अनुरोधकर्ता-स्वामित्व वाली शुरू की गई क्रॉस-एजेंट पंक्तियां, भले ही सामान्य a2a अक्षम हो।agent: केवल समान एजेंट, जब तक कि कोई स्पष्ट स्वामी संबंध यह न कहे कि पंक्ति अनुरोधकर्ता की है।
इससे tree और all मोनोटोनिक बनते हैं: all को ऐसा स्वामित्व वाला चाइल्ड नहीं छिपाना चाहिए
जिसे tree दिखाएगा।
माइग्रेशन योजना
चरण 1: पहचान और लीज़ जोड़ें
- Gateway स्थिति में
gatewayInstanceIdजोड़ें। - ACPX स्थिति डायरेक्टरी के अंतर्गत ACPX लीज़ स्टोर जोड़ें।
- जनरेट किए गए रैपर को शुरू करने से पहले लीज़ लिखें।
- नए ACPX सत्र रिकॉर्ड पर
leaseIdस्टोर करें। - पुराने रिकॉर्ड के लिए मौजूदा PID और कमांड फ़ील्ड रखें।
चरण 2: लीज़-प्रथम सफाई
- बंद करने की सफाई को पहले
leaseIdलोड करने के लिए बदलें। - सिग्नल भेजने से पहले लीज़ के विरुद्ध लाइव प्रक्रिया स्वामित्व सत्यापित करें।
- केवल लेगेसी रिकॉर्ड के लिए वर्तमान रूट PID और रैपर-रूट फ़ॉलबैक रखें।
- सत्यापित सफाई के बाद लीज़ को
closedचिह्नित करें। - सफाई से पहले प्रक्रिया जा चुकी हो तो लीज़ को
lostचिह्नित करें।
चरण 3: लीज़-प्रथम स्टार्टअप रीपिंग
- स्टार्टअप रीपिंग खुली लीज़ स्कैन करती है।
- हर लीज़ के लिए, रूट प्रक्रिया सत्यापित करें और वंशज एकत्र करें।
- सत्यापित वृक्षों को चिल्ड्रेन-प्रथम रीप करें।
- पुराने
closedऔरlostलीज़ को सीमित रिटेंशन विंडो के साथ समाप्त करें। - कमांड-मार्कर स्कैनिंग को केवल अस्थायी लेगेसी फ़ॉलबैक के रूप में रखें, जहां संभव हो रैपर रूट और Gateway इंस्टेंस द्वारा संरक्षित।
चरण 4: सत्र स्वामित्व पंक्तियां
- Gateway सत्र पंक्तियों में स्वामित्व मेटाडेटा जोड़ें।
- ACPX, सबएजेंट, पृष्ठभूमि-कार्य, और सत्र-स्टोर राइटरों को
ownerSessionKeyयाspawnedByभरना सिखाएं। - सत्र दृश्यता जांचों को पंक्ति मेटाडेटा का उपयोग करने में बदलें।
- दृश्यता-समय द्वितीयक
sessions.list({ spawnedBy })लुकअप हटाएं।
चरण 5: लेगेसी हीयूरिस्टिक हटाएं
एक रिलीज़ विंडो के बाद:
- गैर-लेगेसी ACPX सफाई के लिए संग्रहीत रूट कमांड स्ट्रिंग पर निर्भर रहना बंद करें
- कमांड-मार्कर स्टार्टअप स्कैन हटाएं
- दृश्यता फ़ॉलबैक सूची लुकअप हटाएं
- अनुपस्थित या असत्यापनीय लीज़ के लिए रक्षात्मक फेल-क्लोज़्ड व्यवहार रखें
परीक्षण
दो टेबल-ड्रिवन सूट जोड़ें।
प्रक्रिया जीवनचक्र सिम्युलेटर:
- PID का असंबंधित प्रक्रिया द्वारा पुन: उपयोग
- PID का दूसरे Gateway के रैपर रूट द्वारा पुन: उपयोग
- संग्रहीत रैपर कमांड शेल-उद्धृत है, लाइव
psकमांड नहीं है - एडाप्टर चाइल्ड बाहर निकलता है, ग्रैंडचाइल्ड प्रक्रिया समूह में रहता है
- पैरेंट मृत्यु SIGTERM फ़ॉलबैक SIGKILL तक पहुंचता है
- प्रक्रिया सूची अनुपलब्ध
- अनुपस्थित प्रक्रिया वाली बासी लीज़
- रैपर, एडाप्टर चाइल्ड, और ग्रैंडचाइल्ड वाला स्टार्टअप अनाथ
सत्र दृश्यता मैट्रिक्स:
self,tree,agent,all- a2a सक्षम और अक्षम
- समान-एजेंट पंक्ति
- क्रॉस-एजेंट पंक्ति
- अनुरोधकर्ता-स्वामित्व वाली शुरू की गई क्रॉस-एजेंट ACP पंक्ति
- सैंडबॉक्स्ड अनुरोधकर्ता
treeतक सीमित - सूची, इतिहास, भेजना, और स्थिति क्रियाएं
महत्वपूर्ण invariant: अनुरोधकर्ता-स्वामित्व वाला शुरू किया गया चाइल्ड वहां दिखाई देता है जहां
कॉन्फ़िगर की गई दृश्यता में अनुरोधकर्ता सत्र वृक्ष शामिल है, और all, tree से
कम सक्षम नहीं है।
संगतता नोट्स
पुराने सत्र रिकॉर्ड में leaseId नहीं हो सकता। उन्हें लेगेसी
फेल-क्लोज़्ड सफाई पथ का उपयोग करना चाहिए:
- लाइव रूट प्रक्रिया आवश्यक करें
- जब जनरेटेड रैपर अपेक्षित हो, तो रैपर-रूट स्वामित्व आवश्यक करें
- गैर-रैपर रूट के लिए कमांड सहमति आवश्यक करें
- केवल बासी संग्रहीत PID मेटाडेटा के आधार पर कभी सिग्नल न भेजें
यदि कोई लेगेसी रिकॉर्ड सत्यापित नहीं किया जा सकता, तो उसे अकेला छोड़ दें। स्टार्टअप लीज़ सफाई और अगली रिलीज़ विंडो को अंततः फ़ॉलबैक से छुटकारा दिलाना चाहिए।
सफलता मानदंड
- पुराने या बासी ACPX सत्र को बंद करने से दूसरे Gateway की प्रक्रिया खत्म नहीं हो सकती।
- पैरेंट मृत्यु जिद्दी एडाप्टर ग्रैंडचिल्ड्रेन को चलते हुए नहीं छोड़ती।
cancelपुन: उपयोग योग्य सत्र बंद किए बिना सक्रिय टर्न को रोकता है।sessions_listअनुरोधकर्ता-स्वामित्व वाले क्रॉस-एजेंट ACP चिल्ड्रेन कोtreeऔरallदोनों के अंतर्गत दिखा सकता है।- स्टार्टअप सफाई लीज़ द्वारा संचालित होती है, व्यापक कमांड-स्ट्रिंग स्कैन द्वारा नहीं।
- केंद्रित प्रक्रिया और दृश्यता मैट्रिक्स परीक्षण हर उस किनारी मामले को कवर करते हैं जिसके लिए पहले एकबारगी समीक्षा सुधारों की जरूरत पड़ती थी।