डेव टूल्स (adk-devtools)

adk-devtools एक कोडिंग एजेंट के लिए आवश्यक इनर-लूप टूलसेट है — पढ़ना, संपादित करना, खोजना, और चलाना — जिसमें हर ऑपरेशन एक workspace directory तक सीमित होता है। यह एक standalone, publishable crate है जो केवल adk-core पर निर्भर करता है, इसलिए यह किसी भी LlmAgent के साथ compose होता है (CodingAgent harness इसे आपके लिए wire करता है)।

टूल्स

DevToolset एक Toolset है जो छह tools को bundling करता है:

उपकरणपैरामीटरव्यवहार
read_filepath, offset?, limit?फ़ाइल की सामग्री लौटाएँ, पंक्ति-क्रमांक सहित
write_filepath, contentफ़ाइल बनाएं/अधिलेखित करें (मूल निर्देशिकाएँ बनाता है)
edit_filepath, old_string, new_string, replace_all?सटीक-स्ट्रिंग प्रतिस्थापन
globpattern, path?glob से मेल खाने वाली फ़ाइलों की सूची बनाएँ (जैसे src/**/*.rs)
greppattern, path?, glob?, case_insensitive?रेगेक्स सामग्री खोज
bashcommand, timeout_secs?वर्कस्पेस रूट में एक शेल कमांड चलाएँ

जानने योग्य दो सुरक्षा व्यवहार:

  • edit_file को इस फ़ाइल के सत्र में पहले किए गए read_file की आवश्यकता होती है, और डिफ़ॉल्ट रूप से लक्ष्य स्ट्रिंग ठीक एक बार होनी चाहिए (इसे बदलने के लिए replace_all)। यह बिना देखे किए गए ओवरराइट से बचाता है।
  • grep सामान्य build/VCS निर्देशिकाएँ (target, .git, node_modules, …) और binary/oversized फ़ाइलों को छोड़ देता है।

bash टूल अपने stdout/stderr को ToolContext::emit_progress के माध्यम से कमांड चलने के साथ-साथ line-by-line stream करता है, ताकि UIs लाइव terminal दिखा सकें। हर chunk agent की EventStream पर partial event के रूप में आता है (इसे event.tool_progress_stream() से detect करें); पूरा output अभी भी tool के final result के रूप में लौटाया जाता है। देखें streaming_bash example और Streaming Progress from a Tool

Workspace

एक Workspace हर operation को एक directory पर root करता है और एक छोटी policy लागू करता है:

use adk_devtools::Workspace;
use std::time::Duration;

let ws = Workspace::new("./my-repo");              // read-write, bash enabled
let ws = Workspace::read_only("./my-repo");        // explore/plan: no writes, no bash
let ws = Workspace::new("./my-repo")
    .allow_bash(false)                              // file edits, but no shell
    .bash_timeout(Duration::from_secs(60))
    .max_output_bytes(512 * 1024);
  • Path containment — कोई भी path जो root के बाहर resolve होता है, reject कर दिया जाता है, इसलिए agent ../../etc/... को पढ़ या लिख नहीं सकता। Containment को resolved path के विरुद्ध लागू किया जाता है, केवल literal path के विरुद्ध नहीं: root के बाहर point करने वाला symlink lexical रूप से root के अंदर होने पर भी reject हो जाता है। यह symlinked final component और symlinked parent directory दोनों को कवर करता है, इसलिए redirected directory के माध्यम से creation भी refused होती है। जिसका target workspace के अंदर ही रहता है, ऐसा symlink काम करता रहता है, क्योंकि repositories में वैध internal links होते हैं।

    यह check कोई lock नहीं है। check और उसके बाद के open के बीच लगाया गया symlink फिर भी follow किया जाएगा; उस window को बंद करने के लिए descriptor-relative traversal और platform no-follow semantics चाहिए। File tools को ऐसे agent के विरुद्ध containment समझें जो भटक सकता है, न कि ऐसे adversary के विरुद्ध isolation जो concurrent रूप से workspace में लिख सकता है।

  • Read-only modeWorkspace::read_only(..) mutating tools को पूरी तरह छिपा देता है (model को केवल read_file/glob/grep ही दिखते हैं)।

  • bash environment साफ़ किया जाता है — command को केवल PATH, HOME, LANG, LC_ALL, TMPDIR, TERM, USER, और SHELL मिलते हैं, इसलिए agent process द्वारा रखी गई provider API keys env के साथ पढ़ी नहीं जा सकतीं। Workspace::inherit_env(true) पुराने pass-everything व्यवहार को restore करता है, और env_allowlist set को replace करता है।

  • bash timeout + output caps — लंबे या बहुत chatty commands bounded होते हैं। एक timed-out command को process group के रूप में kill किया जाता है, इसलिए उसने जो कुछ शुरू किया था वह भी kill हो जाता है; पहले केवल direct child को signal किया जाता था और descendants जीवित रहते थे।

इसे सीधे उपयोग करना

Toolset को किसी भी agent से attach करें:

use adk_devtools::{DevToolset, Workspace};
use adk_agent::LlmAgentBuilder;
use std::sync::Arc;

let agent = LlmAgentBuilder::new("coder")
    .model(model)
    .toolset(Arc::new(DevToolset::new(Workspace::new("./my-repo"))))
    .build()?;

DevToolset केवल workspace द्वारा अनुमत tools को ही expose करता है, इसलिए read-only workspace अपने आप read-only agent देता है।

सैंडबॉक्सिंग मॉडल

Phase 1 bash को host-local (sh -c, working directory root पर pinned) में timeout और cleared environment के साथ चलाता है। यह क्या देता है और क्या नहीं:

लागूलागू नहीं
File tools root के बाहर resolve नहीं कर सकते, symlinks के माध्यम से भी नहींbash फिर भी absolute paths का उपयोग कर सकता है — working directory एक OS boundary नहीं है
कमांड agent के environment variables को पढ़ नहीं सकताकमांड network तक पहुँच सकता है
एक टाइमआउट कमांड और उसके वंशजों को समाप्त कर देता हैमेमोरी या CPU को कुछ भी सीमित नहीं करता

तो यह पथ-समाहित, पर्यावरण-पृथक, और सीमाबद्ध है, लेकिन OS-पृथक नहीं है। नीति शब्दावली adk-code की SandboxPolicy के अनुरूप है; मज़बूत पृथक्करण के लिए, एक कंटेनरयुक्त executor के पीछे bash चलाएँ (देखें design doc)। adk-guardrail (command allowlists, secret redaction) और tokened tools (e.g. GitHub) के लिए adk-auth के साथ संयोजित करें।

अगला: The harness →