इसे छोड़कर कंटेंट पर जाएं

`/handoff` जनरेशन पाइपलाइन

यह दस्तावेज़ बताता है कि coding-agent आज /handoff को कैसे लागू करता है: ट्रिगर पथ, जनरेशन प्रॉम्प्ट, कम्पलीशन कैप्चर, सेशन स्विच, और संदर्भ पुनःइंजेक्शन।

इसमें शामिल है:

  • इंटरेक्टिव /handoff कमांड डिस्पैच
  • AgentSession.handoff() लाइफसाइकल और स्टेट ट्रांजिशन
  • हैंडऑफ़ आउटपुट को असिस्टेंट आउटपुट से कैसे कैप्चर किया जाता है
  • पुराने/नए सेशन हैंडऑफ़ डेटा को अलग-अलग तरह से कैसे पर्सिस्ट करते हैं
  • सफलता, रद्दीकरण, और विफलता के लिए UI व्यवहार

इसमें शामिल नहीं है:

  • सामान्य ट्री नेविगेशन/ब्रांच इंटर्नल
  • गैर-हैंडऑफ़ सेशन कमांड (/new, /fork, /resume)

इम्प्लीमेंटेशन फ़ाइलें

Section titled “इम्प्लीमेंटेशन फ़ाइलें”
  1. /handoff को बिल्टइन स्लैश कमांड मेटाडेटा (slash-commands.ts) में वैकल्पिक इनलाइन हिंट के साथ घोषित किया गया है: [focus instructions]
  2. इंटरेक्टिव इनपुट हैंडलिंग (InputController) में, /handoff या /handoff ... से मेल खाने वाला सबमिट टेक्स्ट सामान्य प्रॉम्प्ट सबमिशन से पहले इंटरसेप्ट किया जाता है।
  3. एडिटर क्लियर किया जाता है और handleHandoffCommand(customInstructions?) को कॉल किया जाता है।
  4. CommandController.handleHandoffCommand वर्तमान एंट्री का उपयोग करके प्रीफ्लाइट गार्ड करता है:
    • type === "message" एंट्री की गिनती करता है।
    • यदि < 2 है, तो चेतावनी देता है: Nothing to hand off (no messages yet) और वापस लौट जाता है।

यही न्यूनतम-सामग्री गार्ड AgentSession.handoff() के अंदर फिर से मौजूद है और उल्लंघन होने पर एरर थ्रो करता है। यह UI और सेशन दोनों परतों पर सुरक्षा को डुप्लिकेट करता है।

एंड-टू-एंड लाइफसाइकल

Section titled “एंड-टू-एंड लाइफसाइकल”

1) हैंडऑफ़ जनरेशन शुरू करना

Section titled “1) हैंडऑफ़ जनरेशन शुरू करना”

AgentSession.handoff(customInstructions?):

  • वर्तमान ब्रांच एंट्री पढ़ता है (sessionManager.getBranch())
  • न्यूनतम मैसेज काउंट सत्यापित करता है (>= 2)
  • #handoffAbortController बनाता है
  • एक संरचित हैंडऑफ़ दस्तावेज़ का अनुरोध करने वाला फिक्स्ड, इनलाइन प्रॉम्प्ट बनाता है (Goal, Constraints & Preferences, Progress, Key Decisions, Critical Context, Next Steps)
  • यदि कस्टम निर्देश प्रदान किए गए हैं तो Additional focus: ... जोड़ता है

प्रॉम्प्ट इस प्रकार भेजा जाता है:

await this.prompt(handoffPrompt, { expandPromptTemplates: false });

expandPromptTemplates: false इस आंतरिक इंस्ट्रक्शन पेलोड के स्लैश/प्रॉम्प्ट-टेम्पलेट विस्तार को रोकता है।

2) कम्पलीशन कैप्चर करना

Section titled “2) कम्पलीशन कैप्चर करना”

प्रॉम्प्ट भेजने से पहले, handoff() सेशन इवेंट की सदस्यता लेता है और agent_end की प्रतीक्षा करता है।

agent_end पर, यह सबसे हालिया assistant मैसेज के लिए पीछे स्कैन करके एजेंट स्टेट से हैंडऑफ़ टेक्स्ट निकालता है, फिर सभी content ब्लॉक जहाँ type === "text" हैं उन्हें \n के साथ जोड़ता है।

महत्वपूर्ण निष्कर्षण मान्यताएँ:

  • केवल टेक्स्ट ब्लॉक का उपयोग किया जाता है; गैर-टेक्स्ट सामग्री को नज़रअंदाज़ किया जाता है।
  • यह मानता है कि नवीनतम असिस्टेंट मैसेज हैंडऑफ़ जनरेशन से संबंधित है।
  • यह मार्कडाउन सेक्शन को पार्स नहीं करता या फ़ॉर्मेट अनुपालन को सत्यापित नहीं करता।
  • यदि असिस्टेंट आउटपुट में कोई टेक्स्ट ब्लॉक नहीं है, तो हैंडऑफ़ को अनुपस्थित माना जाता है।

handoff() undefined लौटाता है जब कोई भी शर्त पूरी होती है:

  • कोई हैंडऑफ़ टेक्स्ट कैप्चर नहीं हुआ, या
  • #handoffAbortController.signal.aborted सत्य है

यह हमेशा finally में #handoffAbortController को क्लियर करता है।

यदि टेक्स्ट कैप्चर हुआ और अबोर्ट नहीं हुआ:

  1. वर्तमान सेशन राइटर को फ्लश करें (sessionManager.flush())
  2. एक बिल्कुल नया सेशन शुरू करें (sessionManager.newSession())
  3. इन-मेमोरी एजेंट स्टेट रीसेट करें (agent.reset())
  4. agent.sessionId को नए सेशन id से रीबाइंड करें
  5. क्यूड कॉन्टेक्स्ट एरे क्लियर करें (#steeringMessages, #followUpMessages, #pendingNextTurnMessages)
  6. टोडो रिमाइंडर काउंटर रीसेट करें

newSession() एक नया हेडर और खाली एंट्री लिस्ट बनाता है (लीफ null पर रीसेट)। हैंडऑफ़ पथ में, कोई parentSession पास नहीं किया जाता।

5) हैंडऑफ़-कॉन्टेक्स्ट इंजेक्शन

Section titled “5) हैंडऑफ़-कॉन्टेक्स्ट इंजेक्शन”

जेनरेट किए गए हैंडऑफ़ दस्तावेज़ को रैप करके नए सेशन में custom_message एंट्री के रूप में जोड़ा जाता है:

<handoff-context>
...handoff text...
</handoff-context>
The above is a handoff document from a previous session. Use this context to continue the work seamlessly.

इंसर्शन कॉल:

this.sessionManager.appendCustomMessageEntry("handoff", handoffContent, true);

सेमेंटिक्स:

  • customType: "handoff"
  • display: true (TUI रीबिल्ड में दृश्यमान)
  • एंट्री टाइप: custom_message (LLM कॉन्टेक्स्ट में भाग लेता है)

6) सक्रिय एजेंट कॉन्टेक्स्ट रीबिल्ड करना

Section titled “6) सक्रिय एजेंट कॉन्टेक्स्ट रीबिल्ड करना”

इंजेक्शन के बाद:

  1. sessionManager.buildSessionContext() वर्तमान लीफ के लिए मैसेज लिस्ट रिज़ॉल्व करता है
  2. agent.replaceMessages(sessionContext.messages) इंजेक्टेड हैंडऑफ़ मैसेज को सक्रिय कॉन्टेक्स्ट बनाता है
  3. मेथड { document: handoffText } लौटाता है

इस बिंदु पर, नए सेशन में सक्रिय LLM कॉन्टेक्स्ट में पुराने ट्रांस्क्रिप्ट के बजाय इंजेक्टेड हैंडऑफ़ मैसेज होता है।

पर्सिस्टेंस मॉडल: पुराना सेशन बनाम नया सेशन

Section titled “पर्सिस्टेंस मॉडल: पुराना सेशन बनाम नया सेशन”

जनरेशन के दौरान, सामान्य मैसेज पर्सिस्टेंस सक्रिय रहती है। असिस्टेंट हैंडऑफ़ रिस्पॉन्स message_end पर एक नियमित message एंट्री के रूप में पर्सिस्ट किया जाता है।

परिणाम: मूल सेशन में दिखाई देने वाला जेनरेटेड हैंडऑफ़ ऐतिहासिक ट्रांस्क्रिप्ट के भाग के रूप में शामिल होता है।

सेशन रीसेट के बाद, हैंडऑफ़ को customType: "handoff" के साथ custom_message के रूप में पर्सिस्ट किया जाता है।

buildSessionContext() इस एंट्री को createCustomMessage(...) के माध्यम से रनटाइम कस्टम/यूज़र-कॉन्टेक्स्ट मैसेज में कन्वर्ट करता है, इसलिए यह नए सेशन से भविष्य के प्रॉम्प्ट में शामिल होता है।

कंट्रोलर/UI व्यवहार

Section titled “कंट्रोलर/UI व्यवहार”

CommandController.handleHandoffCommand व्यवहार:

  • await session.handoff(customInstructions) को कॉल करता है
  • यदि परिणाम undefined है: showError("Handoff cancelled")
  • सफलता पर:
    • rebuildChatFromMessages() (नया सेशन कॉन्टेक्स्ट लोड करता है, इंजेक्टेड हैंडऑफ़ सहित)
    • स्टेटस लाइन और एडिटर टॉप बॉर्डर को इनवैलिडेट करता है
    • टोडो रीलोड करता है
    • सफलता चैट लाइन जोड़ता है: New session started with handoff context
  • एक्सेप्शन पर:
    • यदि मैसेज "Handoff cancelled" है या एरर नाम AbortError है: showError("Handoff cancelled")
    • अन्यथा: showError("Handoff failed: <message>")
  • अंत में रेंडर का अनुरोध करता है

रद्दीकरण सेमेंटिक्स (वर्तमान व्यवहार)

Section titled “रद्दीकरण सेमेंटिक्स (वर्तमान व्यवहार)”

सेशन-स्तर रद्दीकरण प्रिमिटिव

Section titled “सेशन-स्तर रद्दीकरण प्रिमिटिव”

AgentSession एक्सपोज़ करता है:

  • abortHandoff()#handoffAbortController को अबोर्ट करता है
  • isGeneratingHandoff → कंट्रोलर मौजूद रहने के दौरान true

जब इस अबोर्ट पथ का उपयोग किया जाता है, तो हैंडऑफ़ सब्सक्राइबर Error("Handoff cancelled") के साथ रिजेक्ट करता है, और कमांड कंट्रोलर इसे रद्दीकरण UI में मैप करता है।

इंटरेक्टिव /handoff पथ सीमा

Section titled “इंटरेक्टिव /handoff पथ सीमा”

वर्तमान इंटरेक्टिव कंट्रोलर वायरिंग में, /handoff एक समर्पित Escape हैंडलर इंस्टॉल नहीं करता जो abortHandoff() को कॉल करे (कॉम्पेक्शन/ब्रांच-सारांश पथों के विपरीत जो अस्थायी रूप से editor.onEscape को ओवरराइड करते हैं)।

व्यावहारिक प्रभाव:

  • सेशन-स्तर रद्दीकरण सहायता मौजूद है, लेकिन /handoff कमांड पथ में कोई हैंडऑफ़-विशिष्ट की-बाइंडिंग हुक नहीं है।
  • व्यापक एजेंट अबोर्ट पथों के माध्यम से उपयोगकर्ता व्यवधान अभी भी हो सकता है, लेकिन वह abortHandoff() द्वारा उपयोग किया जाने वाला वही स्पष्ट रद्दीकरण चैनल नहीं है।

अबोर्टेड बनाम विफल हैंडऑफ़

Section titled “अबोर्टेड बनाम विफल हैंडऑफ़”

वर्तमान UI वर्गीकरण:

  • अबोर्टेड/रद्द

    • abortHandoff() पथ "Handoff cancelled" ट्रिगर करता है, या
    • AbortError थ्रो होता है
    • UI दिखाता है Handoff cancelled
  • विफल

    • handoff() / प्रॉम्प्ट पाइपलाइन से कोई भी अन्य थ्रो किया गया एरर (मॉडल/API वैलिडेशन एरर, रनटाइम एक्सेप्शन, आदि)
    • UI दिखाता है Handoff failed: ...

अतिरिक्त बारीकियाँ: यदि जनरेशन पूरी होती है लेकिन कोई टेक्स्ट नहीं निकाला जाता, तो handoff() undefined लौटाता है और कंट्रोलर वर्तमान में रद्द रिपोर्ट करता है, विफल नहीं।

शॉर्ट-सेशन और न्यूनतम-सामग्री गार्डरेल

Section titled “शॉर्ट-सेशन और न्यूनतम-सामग्री गार्डरेल”

दो गार्ड कम-सिग्नल हैंडऑफ़ को रोकते हैं:

  • UI परत (handleHandoffCommand): < 2 मैसेज एंट्री के लिए चेतावनी देता है और जल्दी वापस लौटता है
  • सेशन परत (handoff()): उसी शर्त को एरर के रूप में थ्रो करता है

यह खाली/लगभग-खाली हैंडऑफ़ कॉन्टेक्स्ट के साथ नया सेशन बनाने से बचाता है।

स्टेट ट्रांजिशन सारांश

Section titled “स्टेट ट्रांजिशन सारांश”

उच्च-स्तरीय स्टेट प्रवाह:

  1. इंटरेक्टिव स्लैश कमांड इंटरसेप्ट किया गया
  2. प्रीफ्लाइट मैसेज-काउंट गार्ड
  3. #handoffAbortController बनाया गया (isGeneratingHandoff = true)
  4. आंतरिक हैंडऑफ़ प्रॉम्प्ट सबमिट किया गया (चैट में सामान्य असिस्टेंट जनरेशन के रूप में दृश्यमान)
  5. agent_end पर, अंतिम असिस्टेंट टेक्स्ट निकाला गया
  6. यदि अनुपस्थित/अबोर्टेड → undefined लौटाएं या रद्दीकरण एरर पथ
  7. यदि उपस्थित:
    • पुराना सेशन फ्लश करें
    • नया खाली सेशन बनाएं
    • रनटाइम क्यू/काउंटर रीसेट करें
    • custom_message(handoff) जोड़ें
    • सक्रिय एजेंट मैसेज रीबिल्ड और रिप्लेस करें
  8. कंट्रोलर चैट UI रीबिल्ड करता है और सफलता की घोषणा करता है
  9. #handoffAbortController क्लियर किया गया (isGeneratingHandoff = false)

ज्ञात मान्यताएँ और सीमाएँ

Section titled “ज्ञात मान्यताएँ और सीमाएँ”
  • हैंडऑफ़ निष्कर्षण अनुमानिक है: “अंतिम असिस्टेंट टेक्स्ट ब्लॉक”; कोई संरचनात्मक सत्यापन नहीं।
  • कोई कठोर जाँच नहीं कि जेनरेट किया गया मार्कडाउन अनुरोधित सेक्शन फ़ॉर्मेट का पालन करता है।
  • अनुपस्थित निकाले गए टेक्स्ट को कंट्रोलर UX में रद्दीकरण के रूप में रिपोर्ट किया जाता है।
  • /handoff इंटरेक्टिव प्रवाह में वर्तमान में एक समर्पित Escape→abortHandoff() बाइंडिंग का अभाव है।
  • इस पथ द्वारा नया सेशन वंशावली मेटाडेटा (parentSession) सेट नहीं किया जाता।