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

सत्र स्विचिंग और हालिया सत्र सूची

यह दस्तावेज़ वर्णन करता है कि coding-agent हालिया सत्रों की खोज कैसे करता है, --resume लक्ष्यों को कैसे हल करता है, सत्र पिकर कैसे प्रस्तुत करता है, और सक्रिय रनटाइम सत्र कैसे स्विच करता है।

यह वर्तमान कार्यान्वयन व्यवहार पर केंद्रित है, जिसमें फ़ॉलबैक पथ और चेतावनियाँ शामिल हैं।

कार्यान्वयन फ़ाइलें

Section titled “कार्यान्वयन फ़ाइलें”

डायरेक्टरी स्कोप

Section titled “डायरेक्टरी स्कोप”

SessionManager डिफ़ॉल्ट रूप से सत्रों को cwd-स्कोप्ड डायरेक्टरी में संग्रहीत करता है:

  • ~/.xcsh/agent/sessions/--<cwd-encoded>--/*.jsonl

SessionManager.list(cwd, sessionDir?) केवल उसी डायरेक्टरी को पढ़ता है जब तक कि एक स्पष्ट sessionDir प्रदान न किया जाए।

अलग-अलग पेलोड वाले दो सूचीकरण पथ

Section titled “अलग-अलग पेलोड वाले दो सूचीकरण पथ”

दो अलग-अलग सूचीकरण पाइपलाइन हैं:

  1. getRecentSessions(sessionDir, limit) (स्वागत/सारांश दृश्य)

    • प्रत्येक फ़ाइल से केवल 4KB प्रीफ़िक्स (readTextPrefix(..., 4096)) पढ़ता है।
    • हेडर + सबसे पहले उपयोगकर्ता टेक्स्ट पूर्वावलोकन को पार्स करता है।
    • लेज़ी name और timeAgo गेटर्स के साथ हल्का RecentSessionInfo लौटाता है।
    • फ़ाइल mtime के अनुसार अवरोही क्रम में सॉर्ट करता है।
  2. SessionManager.list(...) / SessionManager.listAll() (रिज़्यूम पिकर और ID मिलान)

    • पूरी सत्र फ़ाइलें पढ़ता है।
    • SessionInfo ऑब्जेक्ट बनाता है (id, cwd, title, messageCount, firstMessage, allMessagesText, टाइमस्टैम्प)।
    • शून्य message प्रविष्टियों वाले सत्रों को छोड़ देता है।
    • modified के अनुसार अवरोही क्रम में सॉर्ट करता है।

मेटाडेटा फ़ॉलबैक व्यवहार

Section titled “मेटाडेटा फ़ॉलबैक व्यवहार”

हालिया सारांशों (RecentSessionInfo) के लिए:

  • प्रदर्शन नाम प्राथमिकता: header.title -> पहला उपयोगकर्ता प्रॉम्प्ट -> header.id -> फ़ाइलनाम
  • कॉम्पैक्ट प्रदर्शन के लिए नाम 40 अक्षरों तक काटा जाता है
  • शीर्षक-व्युत्पन्न नामों से नियंत्रण अक्षर/नई पंक्तियाँ हटा दी जाती हैं/सैनिटाइज़ की जाती हैं

SessionInfo सूची प्रविष्टियों के लिए:

  • title है header.title या नवीनतम कंपैक्शन shortSummary
  • firstMessage पहला उपयोगकर्ता संदेश टेक्स्ट है या "(no messages)"

--continue रिज़ॉल्यूशन और टर्मिनल ब्रेडक्रम्ब प्राथमिकता

Section titled “--continue रिज़ॉल्यूशन और टर्मिनल ब्रेडक्रम्ब प्राथमिकता”

SessionManager.continueRecent(cwd, sessionDir?) इस क्रम में लक्ष्य को हल करता है:

  1. टर्मिनल-स्कोप्ड ब्रेडक्रम्ब पढ़ें (~/.xcsh/agent/terminal-sessions/<terminal-id>)
  2. ब्रेडक्रम्ब सत्यापित करें:
    • वर्तमान टर्मिनल की पहचान की जा सकती है
    • ब्रेडक्रम्ब cwd वर्तमान cwd से मेल खाता है (रिज़ॉल्व्ड पथ तुलना)
    • संदर्भित फ़ाइल अभी भी मौजूद है
  3. यदि ब्रेडक्रम्ब अमान्य/अनुपस्थित है, तो सत्र डायरेक्टरी में mtime के अनुसार सबसे नई फ़ाइल पर फ़ॉलबैक करें (findMostRecentSession)
  4. यदि कोई नहीं मिला, तो नया सत्र बनाएँ

टर्मिनल ID व्युत्पन्न TTY पथ को प्राथमिकता देता है और env-आधारित पहचानकर्ताओं (KITTY_WINDOW_ID, TMUX_PANE, TERM_SESSION_ID, WT_SESSION) पर फ़ॉलबैक करता है।

ब्रेडक्रम्ब लेखन सर्वोत्तम-प्रयास है और गैर-घातक है।

स्टार्टअप-टाइम रिज़्यूम लक्ष्य रिज़ॉल्यूशन (main.ts)

Section titled “स्टार्टअप-टाइम रिज़्यूम लक्ष्य रिज़ॉल्यूशन (main.ts)”

createSessionManager(...) स्ट्रिंग-मूल्य वाले --resume को दो मोड में संभालता है:

  1. पथ-जैसा मान (/, \\ शामिल है, या .jsonl में समाप्त होता है)

    • सीधे SessionManager.open(sessionArg, parsed.sessionDir)
  2. ID प्रीफ़िक्स मान

    • SessionManager.list(cwd, sessionDir) में id.startsWith(sessionArg) द्वारा मिलान खोजें
    • यदि कोई स्थानीय मिलान नहीं और sessionDir बाध्य नहीं है, तो SessionManager.listAll() आज़माएँ
    • पहला मिलान उपयोग किया जाता है (कोई अस्पष्टता प्रॉम्प्ट नहीं)

क्रॉस-प्रोजेक्ट मिलान व्यवहार:

  • यदि मिलान किए गए सत्र का cwd वर्तमान cwd से भिन्न है, तो CLI पूछता है कि वर्तमान प्रोजेक्ट में फ़ॉर्क करना है या नहीं
  • हाँ -> SessionManager.forkFrom(...)
  • नहीं -> त्रुटि फेंकता है (Session "..." is in another project (...))

कोई मिलान नहीं -> त्रुटि फेंकता है (Session "..." not found.)।

प्रारंभिक सत्र-प्रबंधक निर्माण के बाद संभाला जाता है:

  1. SessionManager.list(cwd, parsed.sessionDir) के साथ स्थानीय सत्रों की सूची बनाएँ
  2. यदि खाली: No sessions found प्रिंट करें और जल्दी बाहर निकलें
  3. TUI पिकर खोलें (selectSession)
  4. यदि रद्द किया: No session selected प्रिंट करें और जल्दी बाहर निकलें
  5. यदि चयनित: SessionManager.open(selectedPath)

सीधे SessionManager.continueRecent(...) का उपयोग करता है (ऊपर ब्रेडक्रम्ब-प्रथम व्यवहार)।

पिकर-आधारित चयन आंतरिक विवरण

Section titled “पिकर-आधारित चयन आंतरिक विवरण”

CLI पिकर (src/cli/session-picker.ts)

Section titled “CLI पिकर (src/cli/session-picker.ts)”

selectSession(sessions) SessionSelectorComponent के साथ एक स्टैंडअलोन TUI बनाता है और ठीक एक बार हल करता है:

  • चयन -> चयनित पथ हल करता है
  • रद्द (Esc) -> null हल करता है
  • हार्ड एग्ज़िट (Ctrl+C पथ) -> TUI रोकता है और process.exit(0)

इंटरैक्टिव इन-सत्र पिकर (SelectorController.showSessionSelector)

Section titled “इंटरैक्टिव इन-सत्र पिकर (SelectorController.showSessionSelector)”

प्रवाह:

  1. SessionManager.list(currentCwd, currentSessionDir) के माध्यम से वर्तमान सत्र डायरेक्टरी से सत्र प्राप्त करें
  2. showSelector(...) का उपयोग करके एडिटर क्षेत्र में SessionSelectorComponent माउंट करें
  3. कॉलबैक:
    • चयन -> सेलेक्टर बंद करें और handleResumeSession(sessionPath) कॉल करें
    • रद्द -> एडिटर पुनर्स्थापित करें और रीरेंडर करें
    • बाहर निकलें -> ctx.shutdown()

सत्र सेलेक्टर कम्पोनेंट व्यवहार

Section titled “सत्र सेलेक्टर कम्पोनेंट व्यवहार”

SessionList समर्थन करता है:

  • ऐरो/पेज नेविगेशन
  • Enter चयन के लिए
  • Esc रद्द करने के लिए
  • Ctrl+C बाहर निकलने के लिए
  • सत्र id/title/cwd/first message/all messages/path में फ़ज़ी खोज

खाली-सूची रेंडर व्यवहार:

  • क्रैश होने के बजाय एक संदेश रेंडर करता है
  • खाली पर Enter कुछ नहीं करता (कोई कॉलबैक नहीं)
  • Esc/Ctrl+C अभी भी काम करते हैं

चेतावनी: UI टेक्स्ट कहता है Press Tab to view all, लेकिन इस कम्पोनेंट में वर्तमान में कोई Tab हैंडलर नहीं है और वर्तमान वायरिंग केवल वर्तमान-स्कोप सत्रों की सूची बनाती है।

रनटाइम स्विच निष्पादन (AgentSession.switchSession)

Section titled “रनटाइम स्विच निष्पादन (AgentSession.switchSession)”

switchSession(sessionPath) कोर इन-प्रोसेस स्विच पथ है।

जीवनचक्र/स्थिति संक्रमण:

  1. previousSessionFile कैप्चर करें
  2. session_before_switch हुक इवेंट एमिट करें (reason: "resume", रद्द करने योग्य)
  3. यदि रद्द किया गया -> बिना स्विच के false लौटाएँ
  4. वर्तमान एजेंट इवेंट स्ट्रीम से डिस्कनेक्ट करें
  5. सक्रिय जनरेशन/टूल फ़्लो एबॉर्ट करें
  6. कतारबद्ध स्टीयरिंग/फ़ॉलो-अप/अगला-टर्न संदेश बफ़र साफ़ करें
  7. लंबित लेखन को स्थायी करने के लिए सत्र राइटर फ़्लश करें (sessionManager.flush())
  8. sessionManager.setSessionFile(sessionPath)
    • सत्र फ़ाइल पॉइंटर अपडेट करता है
    • टर्मिनल ब्रेडक्रम्ब लिखता है
    • प्रविष्टियाँ लोड करता है / माइग्रेट करता है / ब्लॉब-रिज़ॉल्व करता है / रीइंडेक्स करता है
    • यदि फ़ाइल डेटा अनुपस्थित/अमान्य है: उस पथ पर एक नया सत्र आरंभ करता है और हेडर पुनर्लिखित करता है
  9. agent.sessionId अपडेट करें
  10. buildSessionContext() के माध्यम से संदर्भ पुनर्निर्माण करें
  11. session_switch हुक इवेंट एमिट करें (reason: "resume", previousSessionFile)
  12. पुनर्निर्मित संदर्भ के साथ एजेंट संदेश बदलें
  13. यदि उपलब्ध और मॉडल रजिस्ट्री में मौजूद है तो sessionContext.models.default से डिफ़ॉल्ट मॉडल पुनर्स्थापित करें
  14. थिंकिंग स्तर पुनर्स्थापित करें:
    • यदि ब्रांच में पहले से thinking_level_change है, तो सहेजा गया सत्र स्तर लागू करें
    • अन्यथा सेटिंग्स से डिफ़ॉल्ट थिंकिंग स्तर प्राप्त करें, मॉडल क्षमता तक सीमित करें, सेट करें, और एक नई thinking_level_change प्रविष्टि जोड़ें
  15. एजेंट श्रोताओं को पुनः कनेक्ट करें और true लौटाएँ

इंटरैक्टिव स्विच के बाद UI स्थिति पुनर्निर्माण

Section titled “इंटरैक्टिव स्विच के बाद UI स्थिति पुनर्निर्माण”

SelectorController.handleResumeSession switchSession के आसपास UI रीसेट करता है:

  • लोडिंग एनिमेशन रोकें
  • स्थिति कंटेनर साफ़ करें
  • लंबित-संदेश UI और लंबित टूल मैप साफ़ करें
  • स्ट्रीमिंग कम्पोनेंट/संदेश संदर्भ रीसेट करें
  • session.switchSession(...) कॉल करें
  • चैट कंटेनर साफ़ करें और सत्र संदर्भ से रीरेंडर करें (renderInitialMessages)
  • नए सत्र आर्टिफ़ैक्ट्स से टूडू पुनः लोड करें
  • Resumed session दिखाएँ

इसलिए दृश्य वार्तालाप/टूडू स्थिति नई सत्र फ़ाइल से पुनर्निर्मित होती है।

स्टार्टअप रिज़्यूम बनाम इन-सत्र स्विच

Section titled “स्टार्टअप रिज़्यूम बनाम इन-सत्र स्विच”

स्टार्टअप रिज़्यूम (--continue, --resume, सीधे खोलना)

Section titled “स्टार्टअप रिज़्यूम (--continue, --resume, सीधे खोलना)”
  • createAgentSession(...) से पहले सत्र फ़ाइल चुनी जाती है।
  • sdk.ts existingSession = sessionManager.buildSessionContext() बनाता है।
  • सत्र निर्माण के दौरान एजेंट संदेश एक बार पुनर्स्थापित किए जाते हैं।
  • निर्माण के दौरान मॉडल/थिंकिंग का चयन किया जाता है (पुनर्स्थापना/फ़ॉलबैक तर्क सहित)।
  • इंटरैक्टिव मोड फिर स्थायी मोड स्थिति (वर्तमान में plan/plan_paused) में पुनः प्रवेश करने के लिए #restoreModeFromSession() चलाता है।

इन-सत्र स्विच (/resume-शैली सेलेक्टर पथ)

Section titled “इन-सत्र स्विच (/resume-शैली सेलेक्टर पथ)”
  • पहले से चल रहे AgentSession पर AgentSession.switchSession(...) का उपयोग करता है।
  • संदेश/मॉडल/थिंकिंग तुरंत यथास्थान पुनर्निर्मित किए जाते हैं।
  • हुक session_before_switch/session_switch इवेंट एमिट किए जाते हैं।
  • UI चैट/टूडू ताज़ा किए जाते हैं।
  • सेलेक्टर फ़्लो में कोई समर्पित पोस्ट-स्विच मोड पुनर्स्थापना कॉल नहीं किया जाता; मोड पुनः-प्रवेश व्यवहार स्टार्टअप #restoreModeFromSession() के साथ सममित नहीं है।

विफलता और एज-केस व्यवहार

Section titled “विफलता और एज-केस व्यवहार”
  • CLI पिकर रद्द -> null लौटाता है, कॉलर No session selected प्रिंट करता है, प्रक्रिया जल्दी बाहर निकलती है।
  • इंटरैक्टिव पिकर रद्द -> एडिटर पुनर्स्थापित, कोई सत्र परिवर्तन नहीं।
  • हुक रद्दीकरण (session_before_switch) -> switchSession() false लौटाता है।
  • CLI --resume (बिना मान): खाली सूची No sessions found प्रिंट करती है और बाहर निकलती है।
  • इंटरैक्टिव सेलेक्टर: खाली सूची संदेश रेंडर करती है और रद्द करने योग्य रहती है।

अनुपस्थित/अमान्य लक्ष्य सत्र फ़ाइल

Section titled “अनुपस्थित/अमान्य लक्ष्य सत्र फ़ाइल”

किसी विशिष्ट पथ पर खोलने/स्विच करने पर (setSessionFile):

  • ENOENT -> खाली माना जाता है -> उसी पथ पर नया सत्र आरंभ और स्थायी किया जाता है।
  • विकृत/अमान्य हेडर (या प्रभावी रूप से अपठनीय पार्स की गई प्रविष्टियाँ) -> खाली माना जाता है -> नया सत्र आरंभ और स्थायी किया जाता है।

यह पुनर्प्राप्ति व्यवहार है, कठोर विफलता नहीं।

स्विच/ओपन वास्तविक I/O विफलताओं (अनुमति त्रुटियाँ, पुनर्लेखन विफलताएँ, आदि) पर अभी भी त्रुटि फेंक सकता है, जो कॉलर्स तक प्रसारित होती हैं।

ID प्रीफ़िक्स मिलान चेतावनियाँ

Section titled “ID प्रीफ़िक्स मिलान चेतावनियाँ”
  • ID मिलान startsWith का उपयोग करता है और सॉर्ट की गई सूची में पहला मिलान लेता है।
  • यदि एकाधिक सत्र प्रीफ़िक्स साझा करते हैं तो कोई अस्पष्टता UI नहीं।
  • SessionManager.list(...) शून्य संदेशों वाले सत्रों को बाहर कर देता है, इसलिए वे सत्र ID मिलान/सूची पिकर के माध्यम से पुनः प्रारंभ योग्य नहीं हैं।