Fundamentals
कॉन्टेक्स्ट इंजन
एक कॉन्टेक्स्ट इंजन नियंत्रित करता है कि OpenClaw प्रत्येक रन के लिए मॉडल कॉन्टेक्स्ट कैसे बनाता है: किन संदेशों को शामिल करना है, पुराने इतिहास का सारांश कैसे बनाना है, और सबएजेंट सीमाओं के आर-पार कॉन्टेक्स्ट कैसे प्रबंधित करना है।
OpenClaw एक अंतर्निहित legacy इंजन के साथ आता है और डिफ़ॉल्ट रूप से उसका उपयोग करता है। कोई Plugin इंजन केवल तभी इंस्टॉल और चुनें, जब आपको अलग असेंबली, Compaction या क्रॉस-सेशन रिकॉल व्यवहार चाहिए।
त्वरित शुरुआत
जाँचें कि कौन-सा इंजन सक्रिय है
openclaw doctor# या कॉन्फ़िगरेशन को सीधे जाँचें:cat ~/.openclaw/openclaw.json | jq '.plugins.slots.contextEngine'Plugin इंजन इंस्टॉल करें
कॉन्टेक्स्ट इंजन Plugins किसी अन्य OpenClaw Plugin की तरह इंस्टॉल किए जाते हैं।
npm से
openclaw plugins install @martian-engineering/lossless-clawस्थानीय पथ से
openclaw plugins install -l ./my-context-engineइंजन सक्षम करें और चुनें
// openclaw.json{ plugins: { slots: { contextEngine: "lossless-claw", // Plugin के पंजीकृत इंजन id से मेल खाना आवश्यक है }, entries: { "lossless-claw": { enabled: true, // Plugin-विशिष्ट कॉन्फ़िगरेशन यहाँ रखें (Plugin के दस्तावेज़ देखें) }, }, },}इंस्टॉल और कॉन्फ़िगर करने के बाद Gateway पुनः आरंभ करें।
पुराने इंजन पर वापस जाएँ (वैकल्पिक)
contextEngine को "legacy" पर सेट करें (या कुंजी पूरी तरह हटा दें—"legacy" डिफ़ॉल्ट है)।
यह कैसे काम करता है
हर बार जब OpenClaw कोई मॉडल प्रॉम्प्ट चलाता है, कॉन्टेक्स्ट इंजन चार जीवनचक्र बिंदुओं पर भाग लेता है:
1. अंतर्ग्रहण
सेशन में नया संदेश जोड़े जाने पर इसे कॉल किया जाता है। इंजन संदेश को अपने डेटा स्टोर में संग्रहीत या इंडेक्स कर सकता है।
2. असेंबल
प्रत्येक मॉडल रन से पहले इसे कॉल किया जाता है। इंजन संदेशों का एक क्रमबद्ध समूह (और एक वैकल्पिक systemPromptAddition) लौटाता है, जो टोकन बजट में समा सके।
3. कॉम्पैक्ट
कॉन्टेक्स्ट विंडो भर जाने पर या उपयोगकर्ता द्वारा /compact चलाने पर इसे कॉल किया जाता है। इंजन स्थान खाली करने के लिए पुराने इतिहास का सारांश बनाता है।
4. टर्न के बाद
रन पूरा होने के बाद इसे कॉल किया जाता है। इंजन स्थिति को स्थायी कर सकता है, पृष्ठभूमि Compaction ट्रिगर कर सकता है या इंडेक्स अपडेट कर सकता है।
इंजन बूटस्ट्रैप, सफल टर्न या Compaction के बाद ट्रांसक्रिप्ट रखरखाव (runtimeContext.rewriteTranscriptEntries() के माध्यम से सुरक्षित पुनर्लेखन) के लिए एक वैकल्पिक maintain() मेथड भी लागू कर सकते हैं। उत्तर को अवरुद्ध करने के बजाय इसे स्थगित कार्य के रूप में चलाने के लिए info.turnMaintenanceMode: "background" सेट करें।
बंडल किए गए गैर-ACP Codex हार्नेस के लिए, OpenClaw असेंबल किए गए कॉन्टेक्स्ट को Codex डेवलपर निर्देशों और वर्तमान टर्न प्रॉम्प्ट में प्रोजेक्ट करके वही जीवनचक्र लागू करता है। Codex अभी भी अपने मूल थ्रेड इतिहास और मूल कॉम्पैक्टर का स्वामित्व रखता है।
सबएजेंट जीवनचक्र (वैकल्पिक)
OpenClaw दो वैकल्पिक सबएजेंट जीवनचक्र हुक कॉल करता है:
prepareSubagentSpawnmethodचाइल्ड रन शुरू होने से पहले साझा कॉन्टेक्स्ट स्थिति तैयार करें। हुक को पैरेंट/चाइल्ड सेशन कुंजियाँ, contextMode (isolated या fork), उपलब्ध ट्रांसक्रिप्ट id/फ़ाइलें और वैकल्पिक TTL प्राप्त होते हैं। यदि यह रोलबैक हैंडल लौटाता है, तो तैयारी सफल होने के बाद स्पॉन विफल होने पर OpenClaw उसे कॉल करता है। lightContext का अनुरोध करने वाले और contextMode="isolated" में रिज़ॉल्व होने वाले मूल सबएजेंट स्पॉन जानबूझकर इस हुक को छोड़ देते हैं, ताकि चाइल्ड कॉन्टेक्स्ट-इंजन-प्रबंधित प्री-स्पॉन स्थिति के बिना हल्के बूटस्ट्रैप कॉन्टेक्स्ट से शुरू हो।
onSubagentEndedmethodसबएजेंट सेशन पूरा होने या स्वीप किए जाने पर सफ़ाई करें।
सिस्टम प्रॉम्प्ट में अतिरिक्त सामग्री
assemble मेथड एक systemPromptAddition स्ट्रिंग लौटा सकता है। OpenClaw इसे रन के सिस्टम प्रॉम्प्ट के आरंभ में जोड़ता है। इससे इंजन स्थिर वर्कस्पेस फ़ाइलों की आवश्यकता के बिना डायनेमिक रिकॉल मार्गदर्शन, पुनर्प्राप्ति निर्देश या कॉन्टेक्स्ट-जागरूक संकेत इंजेक्ट कर सकते हैं।
पुराना इंजन
अंतर्निहित legacy इंजन OpenClaw का मूल व्यवहार सुरक्षित रखता है:
- अंतर्ग्रहण: कोई कार्रवाई नहीं (सेशन मैनेजर संदेशों की स्थायीता सीधे संभालता है)।
- असेंबल: पास-थ्रू (रनटाइम में मौजूदा सैनिटाइज़ → वैलिडेट → लिमिट पाइपलाइन कॉन्टेक्स्ट असेंबली संभालती है)।
- कॉम्पैक्ट: अंतर्निहित सारांशीकरण Compaction को सौंपता है, जो पुराने संदेशों का एक सारांश बनाता है और हाल के संदेशों को अक्षुण्ण रखता है।
- टर्न के बाद: कोई कार्रवाई नहीं।
पुराना इंजन टूल पंजीकृत नहीं करता या systemPromptAddition उपलब्ध नहीं कराता।
जब कोई plugins.slots.contextEngine सेट नहीं होता (या इसे "legacy" पर सेट किया जाता है), तो इस इंजन का स्वचालित रूप से उपयोग किया जाता है।
Plugin इंजन
कोई Plugin, Plugin API का उपयोग करके कॉन्टेक्स्ट इंजन पंजीकृत कर सकता है:
export default function register(api) { api.registerContextEngine("my-engine", (ctx) => ({ info: { id: "my-engine", name: "My Context Engine", ownsCompaction: true, }, async ingest({ sessionId, message, isHeartbeat }) { // संदेश को अपने डेटा स्टोर में संग्रहीत करें return { ingested: true }; }, async assemble({ sessionId, sessionKey, messages, tokenBudget, availableTools, citationsMode, }) { // बजट में समाने वाले संदेश लौटाएँ return { messages: buildContext(messages, tokenBudget), estimatedTokens: countTokens(messages), systemPromptAddition: buildMemorySystemPromptAddition({ availableTools: availableTools ?? new Set(), citationsMode, agentSessionKey: sessionKey, }), }; }, async compact({ sessionId, force }) { // पुराने कॉन्टेक्स्ट का सारांश बनाएँ return { ok: true, compacted: true }; }, }));}फ़ैक्टरी ctx में वैकल्पिक config, agentDir और workspaceDir
मान शामिल होते हैं, ताकि Plugins पहले जीवनचक्र कॉल से पहले प्रति-एजेंट या प्रति-वर्कस्पेस स्थिति
आरंभ कर सकें। किसी गैर-पुराने assemble() कॉल से पहले, होस्ट पंजीकृत
असिंक्रोनस मेमोरी प्रॉम्प्ट तैयारी पूरी करता है। सिंक्रोनस
buildMemorySystemPromptAddition(...) सहायक उस अपरिवर्तनीय रन स्नैपशॉट को पढ़ता है;
दिए गए टूल, उद्धरण, एजेंट और सेशन कॉन्टेक्स्ट को बिना बदलाव के पास करें।
फिर इसे कॉन्फ़िगरेशन में सक्षम करें:
{ plugins: { slots: { contextEngine: "my-engine", }, entries: { "my-engine": { enabled: true, }, }, },}ContextEngine इंटरफ़ेस
आवश्यक सदस्य:
| सदस्य | प्रकार | उद्देश्य |
|---|---|---|
info |
प्रॉपर्टी | इंजन id, नाम, संस्करण और क्या यह Compaction का स्वामी है |
ingest(params) |
मेथड | एक संदेश संग्रहीत करना |
assemble(params) |
मेथड | मॉडल रन के लिए कॉन्टेक्स्ट बनाना (AssembleResult लौटाता है) |
compact(params) |
मेथड | कॉन्टेक्स्ट का सारांश बनाना/कम करना |
assemble निम्न के साथ एक AssembleResult लौटाता है:
messagesMessage[]requiredमॉडल को भेजे जाने वाले क्रमबद्ध संदेश।
estimatedTokensnumberrequiredअसेंबल किए गए कॉन्टेक्स्ट में कुल टोकन का इंजन-अनुमान। OpenClaw इसका उपयोग Compaction सीमा संबंधी निर्णयों और नैदानिक रिपोर्टिंग के लिए करता है।
systemPromptAdditionstringसिस्टम प्रॉम्प्ट के आरंभ में जोड़ा जाता है।
promptAuthority"assembled" | "preassembly_may_overflow"नियंत्रित करता है कि रनर पूर्व-सक्रिय ओवरफ़्लो
पूर्व-जाँचों के लिए किस टोकन अनुमान का उपयोग करता है। डिफ़ॉल्ट "assembled" है, जिसका अर्थ है कि Compaction का स्वामित्व न रखने वाले इंजनों के लिए केवल असेंबल किए गए
प्रॉम्प्ट के अनुमान की जाँच होती है।
ownsCompaction: true सेट करने वाले इंजन अपना प्रॉम्प्ट प्रवेश स्वयं प्रबंधित करते हैं,
इसलिए OpenClaw डिफ़ॉल्ट रूप से सामान्य प्री-प्रॉम्प्ट पूर्व-जाँच छोड़ देता है। "preassembly_may_overflow" केवल तभी सेट करें, जब आपका असेंबल किया गया दृश्य
अंतर्निहित ट्रांसक्रिप्ट में ओवरफ़्लो
जोखिम छिपा सकता हो; तब रनर सामान्य
पूर्व-जाँच सक्रिय रखता है और पूर्व-सक्रिय रूप से
कॉम्पैक्ट करने का निर्णय लेते समय असेंबल किए गए अनुमान तथा प्री-असेंबली (बिना विंडो वाले) सेशन-इतिहास अनुमान में से अधिकतम मान लेता है।
दोनों ही स्थितियों में, आपके लौटाए गए संदेश ही
मॉडल देखता है—promptAuthority केवल पूर्व-जाँच को प्रभावित करता है।
contextProjectionContextEngineProjectionस्थायी बैकएंड थ्रेड वाले होस्ट (उदाहरण के लिए Codex app-server) के लिए वैकल्पिक प्रोजेक्शन जीवनचक्र। स्थिर epoch के साथ mode: "thread_bootstrap" होस्ट से असेंबल किए गए कॉन्टेक्स्ट को प्रत्येक युग में एक बार इंजेक्ट करने और युग बदलने तक बैकएंड थ्रेड का पुनः उपयोग करने को कहता है, बजाय प्रत्येक टर्न में दोबारा प्रोजेक्ट करने के। सामान्य प्रति-टर्न प्रोजेक्शन के लिए इस फ़ील्ड को छोड़ दें।
compact एक CompactResult लौटाता है। जब Compaction सक्रिय सेशन
पहचान बदलता है, तो result.sessionTarget (सेशन पहचान और स्टोर स्कोप रखने वाला एक टाइप किया हुआ ContextEngineSessionTarget)
उस उत्तराधिकारी सेशन की पहचान करता है जिसका उपयोग अगली पुनः कोशिश या टर्न को करना आवश्यक है;
result.sessionId उत्तराधिकारी id को प्रतिबिंबित करता है।
वैकल्पिक सदस्य:
| सदस्य | प्रकार | उद्देश्य |
|---|---|---|
bootstrap(params) |
मेथड | सेशन के लिए इंजन स्थिति आरंभ करना। इंजन द्वारा किसी सेशन को पहली बार देखने पर एक बार कॉल किया जाता है (उदाहरण के लिए, इतिहास आयात करना)। |
maintain(params) |
मेथड | बूटस्ट्रैप, सफल टर्न या Compaction के बाद ट्रांसक्रिप्ट रखरखाव। सुरक्षित पुनर्लेखन के लिए runtimeContext.rewriteTranscriptEntries() का उपयोग करें। |
ingestBatch(params) |
मेथड | पूरे हो चुके टर्न को बैच के रूप में अंतर्ग्रहण करना। रन पूरा होने के बाद उस टर्न के सभी संदेशों के साथ एक बार कॉल किया जाता है। |
afterTurn(params) |
मेथड | रन-पश्चात जीवनचक्र कार्य (स्थिति को स्थायी करना, पृष्ठभूमि Compaction ट्रिगर करना)। |
prepareSubagentSpawn(params) |
मेथड | चाइल्ड सेशन शुरू होने से पहले उसके लिए साझा स्थिति सेट अप करना। |
onSubagentEnded(params) |
मेथड | सबएजेंट समाप्त होने के बाद सफ़ाई करना। |
dispose() |
मेथड | संसाधन मुक्त करना। Gateway बंद होने या Plugin पुनः लोड होने के दौरान कॉल किया जाता है—प्रति-सेशन नहीं। |
रनटाइम सेटिंग्स
OpenClaw के भीतर चलने वाले जीवनचक्र हुक को एक वैकल्पिक
runtimeSettings ऑब्जेक्ट प्राप्त होता है। यह संस्करणित, केवल-पठन आंतरिक
प्रोड्यूसर/कंज़्यूमर API सतह है: OpenClaw इसे चयनित कॉन्टेक्स्ट
इंजन के लिए उत्पन्न करता है और कॉन्टेक्स्ट इंजन जीवनचक्र हुक के भीतर इसका उपभोग करता है। इसे
सीधे उपयोगकर्ताओं के लिए रेंडर नहीं किया जाता और यह कोई समर्पित रिपोर्टिंग सतह नहीं बनाता।
schemaVersion: वर्तमान में1runtime: OpenClaw होस्ट, रनटाइम मोड (normal,fallback, याdegraded), और वैकल्पिक हार्नेस/रनटाइम आईडीcontextEngineSelection: चयनित संदर्भ इंजन आईडी और चयन स्रोतexecutionHost: हुक का आह्वान करने वाली सतह की होस्ट आईडी और लेबलmodel: अनुरोधित मॉडल, निर्धारित मॉडल, प्रदाता, और वैकल्पिक मॉडल परिवारlimits: ज्ञात होने पर प्रॉम्प्ट टोकन बजट और अधिकतम आउटपुट टोकनdiagnostics: ज्ञात होने पर क्लोज़्ड फ़ॉलबैक और निम्नीकृत कारण कोड
जो फ़ील्ड अज्ञात हो सकते हैं, उन्हें null के रूप में दर्शाया जाता है; रनटाइम मोड और चयन स्रोत जैसे
डिस्क्रिमिनेटर फ़ील्ड नॉन-नलेबल रहते हैं। पुराने इंजन संगत रहते हैं:
यदि कोई सख्त लेगेसी इंजन runtimeSettings को अज्ञात प्रॉपर्टी के रूप में अस्वीकार करता है,
तो OpenClaw इंजन को क्वारंटीन करने के बजाय उसके बिना लाइफ़साइकल कॉल का
पुनः प्रयास करता है।
होस्ट आवश्यकताएँ
संदर्भ इंजन info.hostRequirements पर होस्ट क्षमता आवश्यकताएँ घोषित कर सकते हैं।
OpenClaw ऑपरेशन शुरू करने से पहले इन आवश्यकताओं की जाँच करता है और जब चयनित
रनटाइम उन्हें पूरा नहीं कर सकता, तो वर्णनात्मक त्रुटि के साथ फ़ेल-क्लोज़्ड होता है।
एजेंट रन के लिए, जब इंजन को assemble() के माध्यम से
वास्तविक मॉडल प्रॉम्प्ट नियंत्रित करना आवश्यक हो, तो assemble-before-prompt घोषित करें:
info: { id: "my-context-engine", name: "My Context Engine", hostRequirements: { "agent-run": { requiredCapabilities: ["assemble-before-prompt"], unsupportedMessage: "नेटिव Codex या OpenClaw एम्बेडेड रनटाइम का उपयोग करें, या लेगेसी संदर्भ इंजन चुनें।", }, },}नेटिव Codex और OpenClaw एम्बेडेड एजेंट रन assemble-before-prompt को पूरा करते हैं।
जेनेरिक CLI बैकएंड ऐसा नहीं करते, इसलिए इसकी आवश्यकता रखने वाले इंजनों को
CLI प्रक्रिया शुरू होने से पहले अस्वीकार कर दिया जाता है।
विफलता पृथक्करण
OpenClaw चयनित Plugin इंजन को कोर उत्तर पथ से अलग रखता है। यदि कोई
गैर-लेगेसी इंजन अनुपस्थित है, अनुबंध सत्यापन में विफल होता है, फ़ैक्टरी
निर्माण के दौरान अपवाद उत्पन्न करता है, या किसी लाइफ़साइकल विधि से अपवाद उत्पन्न करता है,
तो OpenClaw वर्तमान Gateway प्रक्रिया के लिए उस इंजन को क्वारंटीन करता है और
संदर्भ-इंजन कार्य को अंतर्निहित legacy इंजन पर डाउनग्रेड कर देता है।
विफल ऑपरेशन के साथ त्रुटि लॉग की जाती है, ताकि ऑपरेटर एजेंट को
मौन किए बिना Plugin की मरम्मत, अपडेट या उसे अक्षम कर सके।
होस्ट आवश्यकता विफलताएँ अलग होती हैं: जब कोई इंजन घोषित करता है कि रनटाइम में आवश्यक क्षमता नहीं है, तो OpenClaw रन शुरू करने से पहले फ़ेल-क्लोज़्ड होता है। यह उन इंजनों की सुरक्षा करता है जो किसी असमर्थित होस्ट में चलने पर स्थिति को दूषित कर देंगे।
ownsCompaction
ownsCompaction नियंत्रित करता है कि रन के लिए OpenClaw रनटाइम का अंतर्निहित इन-अटेम्प्ट ऑटो-कॉम्पैक्शन सक्षम रहता है या नहीं:
ownsCompaction: true
इंजन कॉम्पैक्शन व्यवहार का स्वामी होता है। OpenClaw उस रन के लिए OpenClaw रनटाइम के अंतर्निहित ऑटो-कॉम्पैक्शन और जेनेरिक प्री-प्रॉम्प्ट ओवरफ़्लो प्रीचेक को अक्षम करता है, और इंजन का compact() कार्यान्वयन /compact, प्रदाता ओवरफ़्लो रिकवरी कॉम्पैक्शन, और afterTurn() में किए जाने वाले किसी भी सक्रिय कॉम्पैक्शन के लिए उत्तरदायी होता है। जब इंजन assemble() से promptAuthority: "preassembly_may_overflow" लौटाता है, तब भी OpenClaw प्री-प्रॉम्प्ट ओवरफ़्लो सुरक्षा उपाय चलाता है।
ownsCompaction: false or unset
प्रॉम्प्ट निष्पादन के दौरान OpenClaw रनटाइम का अंतर्निहित ऑटो-कॉम्पैक्शन अभी भी चल सकता है, लेकिन सक्रिय इंजन की compact() विधि को फिर भी /compact और ओवरफ़्लो रिकवरी के लिए कॉल किया जाता है।
इसका अर्थ है कि दो मान्य Plugin पैटर्न हैं:
स्वामित्व मोड
अपना कॉम्पैक्शन एल्गोरिदम लागू करें और ownsCompaction: true सेट करें।
प्रत्यायोजन मोड
ownsCompaction: false सेट करें और OpenClaw के अंतर्निहित कॉम्पैक्शन व्यवहार का उपयोग करने के लिए compact() से delegateCompactionToRuntime(...) को openclaw/plugin-sdk/core कॉल करवाएँ।
सक्रिय गैर-स्वामी इंजन के लिए निष्क्रिय compact() असुरक्षित है, क्योंकि यह उस इंजन स्लॉट के सामान्य /compact और ओवरफ़्लो-रिकवरी कॉम्पैक्शन पथ को अक्षम कर देता है।
कॉन्फ़िगरेशन संदर्भ
{ plugins: { slots: { // सक्रिय संदर्भ इंजन चुनें। डिफ़ॉल्ट: "legacy"। // Plugin इंजन का उपयोग करने के लिए इसे Plugin आईडी पर सेट करें। contextEngine: "legacy", }, },}कॉम्पैक्शन और मेमोरी से संबंध
कॉम्पैक्शन
कॉम्पैक्शन संदर्भ इंजन की एक जिम्मेदारी है। लेगेसी इंजन OpenClaw के अंतर्निहित सारांशीकरण को कार्य सौंपता है। Plugin इंजन कोई भी कॉम्पैक्शन रणनीति (DAG सारांश, वेक्टर पुनर्प्राप्ति आदि) लागू कर सकते हैं।
मेमोरी Plugin
मेमोरी Plugin (plugins.slots.memory) संदर्भ इंजनों से अलग होते हैं। मेमोरी Plugin खोज/पुनर्प्राप्ति प्रदान करते हैं; संदर्भ इंजन नियंत्रित करते हैं कि मॉडल क्या देखता है। वे साथ मिलकर काम कर सकते हैं - कोई संदर्भ इंजन संयोजन के दौरान मेमोरी Plugin डेटा का उपयोग कर सकता है। सक्रिय मेमोरी प्रॉम्प्ट पथ चाहने वाले Plugin इंजनों को openclaw/plugin-sdk/core से buildMemorySystemPromptAddition(...) का उपयोग करना चाहिए, जो मेमोरी-Plugin लेआउट को उजागर किए बिना होस्ट द्वारा तैयार मेमोरी प्रॉम्प्ट अनुभागों को पहले जोड़ने के लिए तैयार systemPromptAddition में बदल देता है।
सत्र प्रूनिंग
इन-मेमोरी पुराने टूल परिणामों की ट्रिमिंग सक्रिय संदर्भ इंजन से स्वतंत्र रूप से चलती रहती है।
सुझाव
- यह सत्यापित करने के लिए
openclaw doctorका उपयोग करें कि आपका इंजन सही ढंग से लोड हो रहा है। - इंजन बदलने पर, मौजूदा सत्र अपने वर्तमान इतिहास के साथ जारी रहते हैं। नया इंजन भविष्य के रन संभालता है।
- इंजन त्रुटियाँ लॉग की जाती हैं और चयनित Plugin इंजन को वर्तमान Gateway प्रक्रिया के लिए क्वारंटीन किया जाता है। उत्तर जारी रह सकें, इसलिए उपयोगकर्ता टर्न के लिए OpenClaw
legacyपर फ़ॉलबैक करता है, लेकिन आपको फिर भी खराब Plugin की मरम्मत, उसे अपडेट, अक्षम या अनइंस्टॉल करना चाहिए। - डेवलपमेंट के लिए, स्थानीय Plugin डायरेक्टरी को कॉपी किए बिना लिंक करने हेतु
openclaw plugins install -l ./my-engineका उपयोग करें।
संबंधित
- Compaction - लंबी बातचीत का सारांश बनाना
- संदर्भ - एजेंट टर्न के लिए संदर्भ कैसे बनाया जाता है
- Plugin आर्किटेक्चर - संदर्भ इंजन Plugin पंजीकृत करना
- Plugin मैनिफ़ेस्ट - Plugin मैनिफ़ेस्ट फ़ील्ड
- Plugin - Plugin का अवलोकन