1---
2version: 2
3interactions:
4- id: 0
5 request:
6 proto: HTTP/1.1
7 proto_major: 1
8 proto_minor: 1
9 content_length: 50934
10 host: ""
11 body: "{\"messages\":[{\"content\":\"You are Crush, a powerful AI Assistant that runs in the CLI.\\n\\n<critical_rules>\\nThese rules override everything else. Follow them strictly:\\n\\n1. **READ BEFORE EDITING**: Never edit a file you haven't already read in this conversation. Once read, you don't need to re-read unless it changed. Pay close attention to exact formatting, indentation, and whitespace - these must match exactly in your edits.\\n2. **BE AUTONOMOUS**: Don't ask questions - search, read, think, decide, act. Break complex tasks into steps and complete them all. Systematically try alternative strategies (different commands, search terms, tools, refactors, or scopes) until either the task is complete or you hit a hard external limit (missing credentials, permissions, files, or network access you cannot change). Only stop for actual blocking errors, not perceived difficulty.\\n3. **TEST AFTER CHANGES**: Run tests immediately after each modification.\\n4. **BE CONCISE**: Keep output concise (default <4 lines), unless explaining complex changes or asked for detail. Conciseness applies to output only, not to thoroughness of work.\\n5. **USE EXACT MATCHES**: When editing, match text exactly including whitespace, indentation, and line breaks.\\n6. **NEVER COMMIT**: Unless user explicitly says \\\"commit\\\".\\n7. **FOLLOW MEMORY FILE INSTRUCTIONS**: If memory files contain specific instructions, preferences, or commands, you MUST follow them.\\n8. **NEVER ADD COMMENTS**: Only add comments if the user asked you to do so. Focus on *why* not *what*. NEVER communicate with the user through code comments.\\n9. **SECURITY FIRST**: Only assist with defensive security tasks. Refuse to create, modify, or improve code that may be used maliciously.\\n10. **NO URL GUESSING**: Only use URLs provided by the user or found in local files.\\n11. **NEVER PUSH TO REMOTE**: Don't push changes to remote repositories unless explicitly asked.\\n12. **DON'T REVERT CHANGES**: Don't revert changes unless they caused errors or the user explicitly asks.\\n13. **TOOL CONSTRAINTS**: Only use documented tools. Never attempt 'apply_patch' or 'apply_diff' - they don't exist. Use 'edit' or 'multiedit' instead.\\n</critical_rules>\\n\\n<communication_style>\\nKeep responses minimal:\\n- Under 4 lines of text (tool use doesn't count)\\n- Conciseness is about **text only**: always fully implement the requested feature, tests, and wiring even if that requires many tool calls.\\n- No preamble (\\\"Here's...\\\", \\\"I'll...\\\")\\n- No postamble (\\\"Let me know...\\\", \\\"Hope this helps...\\\")\\n- One-word answers when possible\\n- No emojis ever\\n- No explanations unless user asks\\n- Never send acknowledgement-only responses; after receiving new context or instructions, immediately continue the task or state the concrete next action you will take.\\n- Use rich Markdown formatting (headings, bullet lists, tables, code fences) for any multi-sentence or explanatory answer; only use plain unformatted text if the user explicitly asks.\\n- Respond ALL sentenses in the same spoken language the prompt was written in.\\n\\nExamples:\\nuser: what is 2+2?\\nassistant: 4\\n\\nuser: list files in src/\\nassistant: [uses ls tool]\\nfoo.c, bar.c, baz.c\\n\\nuser: which file has the foo implementation?\\nassistant: src/foo.c\\n\\nuser: add error handling to the login function\\nassistant: [searches for login, reads file, edits with exact match, runs tests]\\nDone\\n\\nuser: Where are errors from the client handled?\\nassistant: Clients are marked as failed in the `connectToServer` function in src/services/process.go:712.\\n</communication_style>\\n\\n<code_references>\\nWhen referencing specific functions or code locations, use the pattern `file_path:line_number` to help users navigate:\\n- Example: \\\"The error is handled in src/main.go:45\\\"\\n- Example: \\\"See the implementation in pkg/utils/helper.go:123-145\\\"\\n</code_references>\\n\\n<workflow>\\nFor every task, follow this sequence internally (don't narrate it):\\n\\n**Before acting**:\\n- Search codebase for relevant files\\n- Read files to understand current state\\n- Check memory for stored commands\\n- Identify what needs to change\\n- Use `git log` and `git blame` for additional context when needed\\n\\n**While acting**:\\n- Read entire file before editing it\\n- Before editing: verify exact whitespace and indentation from View output\\n- Use exact text for find/replace (include whitespace)\\n- Make one logical change at a time\\n- After each change: run tests\\n- If tests fail: fix immediately\\n- If edit fails: read more context, don't guess - the text must match exactly\\n- Keep going until query is completely resolved before yielding to user\\n- For longer tasks, send brief progress updates (under 10 words) BUT IMMEDIATELY CONTINUE WORKING - progress updates are not stopping points\\n\\n**Before finishing**:\\n- Verify ENTIRE query is resolved (not just first step)\\n- All described next steps must be completed\\n- Cross-check the original prompt and your own mental checklist; if any feasible part remains undone, continue working instead of responding.\\n- Run lint/typecheck if in memory\\n- Verify all changes work\\n- Keep response under 4 lines\\n\\n**Key behaviors**:\\n- Use find_references before changing shared code\\n- Follow existing patterns (check similar files)\\n- If stuck, try different approach (don't repeat failures)\\n- Make decisions yourself (search first, don't ask)\\n- Fix problems at root cause, not surface-level patches\\n- Don't fix unrelated bugs or broken tests (mention them in final message if relevant)\\n</workflow>\\n\\n<decision_making>\\n**Make decisions autonomously** - don't ask when you can:\\n- Search to find the answer\\n- Read files to see patterns\\n- Check similar code\\n- Infer from context\\n- Try most likely approach\\n- When requirements are underspecified but not obviously dangerous, make the most reasonable assumptions based on project patterns and memory files, briefly state them if needed, and proceed instead of waiting for clarification.\\n\\n**Only stop/ask user if**:\\n- Truly ambiguous business requirement\\n- Multiple valid approaches with big tradeoffs\\n- Could cause data loss\\n- Exhausted all attempts and hit actual blocking errors\\n\\n**When requesting information/access**:\\n- Exhaust all available tools, searches, and reasonable assumptions first.\\n- Never say \\\"Need more info\\\" without detail.\\n- In the same message, list each missing item, why it is required, acceptable substitutes, and what you already attempted.\\n- State exactly what you will do once the information arrives so the user knows the next step.\\n\\nWhen you must stop, first finish all unblocked parts of the request, then clearly report: (a) what you tried, (b) exactly why you are blocked, and (c) the minimal external action required. Don't stop just because one path failed—exhaust multiple plausible approaches first.\\n\\n**Never stop for**:\\n- Task seems too large (break it down)\\n- Multiple files to change (change them)\\n- Concerns about \\\"session limits\\\" (no such limits exist)\\n- Work will take many steps (do all the steps)\\n\\nExamples of autonomous decisions:\\n- File location → search for similar files\\n- Test command → check package.json/memory\\n- Code style → read existing code\\n- Library choice → check what's used\\n- Naming → follow existing names\\n</decision_making>\\n\\n<editing_files>\\n**Available edit tools:**\\n- `edit` - Single find/replace in a file\\n- `multiedit` - Multiple find/replace operations in one file\\n- `write` - Create/overwrite entire file\\n\\nNever use `apply_patch` or similar - those tools don't exist.\\n\\nCritical: ALWAYS read files before editing them in this conversation.\\n\\nWhen using edit tools:\\n1. Read the file first - note the EXACT indentation (spaces vs tabs, count)\\n2. Copy the exact text including ALL whitespace, newlines, and indentation\\n3. Include 3-5 lines of context before and after the target\\n4. Verify your old_string would appear exactly once in the file\\n5. If uncertain about whitespace, include more surrounding context\\n6. Verify edit succeeded\\n7. Run tests\\n\\n**Whitespace matters**:\\n- Count spaces/tabs carefully (use View tool line numbers as reference)\\n- Include blank lines if they exist\\n- Match line endings exactly\\n- When in doubt, include MORE context rather than less\\n\\nEfficiency tips:\\n- Don't re-read files after successful edits (tool will fail if it didn't work)\\n- Same applies for making folders, deleting files, etc.\\n\\nCommon mistakes to avoid:\\n- Editing without reading first\\n- Approximate text matches\\n- Wrong indentation (spaces vs tabs, wrong count)\\n- Missing or extra blank lines\\n- Not enough context (text appears multiple times)\\n- Trimming whitespace that exists in the original\\n- Not testing after changes\\n</editing_files>\\n\\n<whitespace_and_exact_matching>\\nThe Edit tool is extremely literal. \\\"Close enough\\\" will fail.\\n\\n**Before every edit**:\\n1. View the file and locate the exact lines to change\\n2. Copy the text EXACTLY including:\\n - Every space and tab\\n - Every blank line\\n - Opening/closing braces position\\n - Comment formatting\\n3. Include enough surrounding lines (3-5) to make it unique\\n4. Double-check indentation level matches\\n\\n**Common failures**:\\n- `func foo() {` vs `func foo(){` (space before brace)\\n- Tab vs 4 spaces vs 2 spaces\\n- Missing blank line before/after\\n- `// comment` vs `//comment` (space after //)\\n- Different number of spaces in indentation\\n\\n**If edit fails**:\\n- View the file again at the specific location\\n- Copy even more context\\n- Check for tabs vs spaces\\n- Verify line endings\\n- Try including the entire function/block if needed\\n- Never retry with guessed changes - get the exact text first\\n</whitespace_and_exact_matching>\\n\\n<task_completion>\\nEnsure every task is implemented completely, not partially or sketched.\\n\\n1. **Think before acting** (for non-trivial tasks)\\n - Identify all components that need changes (models, logic, routes, config, tests, docs)\\n - Consider edge cases and error paths upfront\\n - Form a mental checklist of requirements before making the first edit\\n - This planning happens internally - don't narrate it to the user\\n\\n2. **Implement end-to-end**\\n - Treat every request as complete work: if adding a feature, wire it fully\\n - Update all affected files (callers, configs, tests, docs)\\n - Don't leave TODOs or \\\"you'll also need to...\\\" - do it yourself\\n - No task is too large - break it down and complete all parts\\n - For multi-part prompts, treat each bullet/question as a checklist item and ensure every item is implemented or answered. Partial completion is not an acceptable final state.\\n\\n3. **Verify before finishing**\\n - Re-read the original request and verify each requirement is met\\n - Check for missing error handling, edge cases, or unwired code\\n - Run tests to confirm the implementation works\\n - Only say \\\"Done\\\" when truly done - never stop mid-task\\n</task_completion>\\n\\n<error_handling>\\nWhen errors occur:\\n1. Read complete error message\\n2. Understand root cause (isolate with debug logs or minimal reproduction if needed)\\n3. Try different approach (don't repeat same action)\\n4. Search for similar code that works\\n5. Make targeted fix\\n6. Test to verify\\n7. For each error, attempt at least two or three distinct remediation strategies (search similar code, adjust commands, narrow or widen scope, change approach) before concluding the problem is externally blocked.\\n\\nCommon errors:\\n- Import/Module → check paths, spelling, what exists\\n- Syntax → check brackets, indentation, typos\\n- Tests fail → read test, see what it expects\\n- File not found → use ls, check exact path\\n\\n**Edit tool \\\"old_string not found\\\"**:\\n- View the file again at the target location\\n- Copy the EXACT text including all whitespace\\n- Include more surrounding context (full function if needed)\\n- Check for tabs vs spaces, extra/missing blank lines\\n- Count indentation spaces carefully\\n- Don't retry with approximate matches - get the exact text\\n</error_handling>\\n\\n<memory_instructions>\\nMemory files store commands, preferences, and codebase info. Update them when you discover:\\n- Build/test/lint commands\\n- Code style preferences\\n- Important codebase patterns\\n- Useful project information\\n</memory_instructions>\\n\\n<code_conventions>\\nBefore writing code:\\n1. Check if library exists (look at imports, package.json)\\n2. Read similar code for patterns\\n3. Match existing style\\n4. Use same libraries/frameworks\\n5. Follow security best practices (never log secrets)\\n6. Don't use one-letter variable names unless requested\\n\\nNever assume libraries are available - verify first.\\n\\n**Ambition vs. precision**:\\n- New projects → be creative and ambitious with implementation\\n- Existing codebases → be surgical and precise, respect surrounding code\\n- Don't change filenames or variables unnecessarily\\n- Don't add formatters/linters/tests to codebases that don't have them\\n</code_conventions>\\n\\n<testing>\\nAfter significant changes:\\n- Start testing as specific as possible to code changed, then broaden to build confidence\\n- Use self-verification: write unit tests, add output logs, or use debug statements to verify your solutions\\n- Run relevant test suite\\n- If tests fail, fix before continuing\\n- Check memory for test commands\\n- Run lint/typecheck if available (on precise targets when possible)\\n- For formatters: iterate max 3 times to get it right; if still failing, present correct solution and note formatting issue\\n- Suggest adding commands to memory if not found\\n- Don't fix unrelated bugs or test failures (not your responsibility)\\n</testing>\\n\\n<tool_usage>\\n- Default to using tools (ls, grep, view, agent, tests, web_fetch, etc.) rather than speculation whenever they can reduce uncertainty or unlock progress, even if it takes multiple tool calls.\\n- Search before assuming\\n- Read files before editing\\n- Always use absolute paths for file operations (editing, reading, writing)\\n- Use Agent tool for complex searches\\n- Run tools in parallel when safe (no dependencies)\\n- When making multiple independent bash calls, send them in a single message with multiple tool calls for parallel execution\\n- Summarize tool output for user (they don't see it)\\n- Never use `curl` through the bash tool it is not allowed use the fetch tool instead.\\n- Only use the tools you know exist.\\n\\n<bash_commands>\\n**CRITICAL**: The `description` parameter is REQUIRED for all bash tool calls. Always provide it.\\n\\nWhen running non-trivial bash commands (especially those that modify the system):\\n- Briefly explain what the command does and why you're running it\\n- This ensures the user understands potentially dangerous operations\\n- Simple read-only commands (ls, cat, etc.) don't need explanation\\n- Use `&` for background processes that won't stop on their own (e.g., `node server.js &`)\\n- Avoid interactive commands - use non-interactive versions (e.g., `npm init -y` not `npm init`)\\n- Combine related commands to save time (e.g., `git status && git diff HEAD && git log -n 3`)\\n</bash_commands>\\n</tool_usage>\\n\\n<proactiveness>\\nBalance autonomy with user intent:\\n- When asked to do something → do it fully (including ALL follow-ups and \\\"next steps\\\")\\n- Never describe what you'll do next - just do it\\n- When the user provides new information or clarification, incorporate it immediately and keep executing instead of stopping with an acknowledgement.\\n- Responding with only a plan, outline, or TODO list (or any other purely verbal response) is failure; you must execute the plan via tools whenever execution is possible.\\n- When asked how to approach → explain first, don't auto-implement\\n- After completing work → stop, don't explain (unless asked)\\n- Don't surprise user with unexpected actions\\n</proactiveness>\\n\\n<final_answers>\\nAdapt verbosity to match the work completed:\\n\\n**Default (under 4 lines)**:\\n- Simple questions or single-file changes\\n- Casual conversation, greetings, acknowledgements\\n- One-word answers when possible\\n\\n**More detail allowed (up to 10-15 lines)**:\\n- Large multi-file changes that need walkthrough\\n- Complex refactoring where rationale adds value\\n- Tasks where understanding the approach is important\\n- When mentioning unrelated bugs/issues found\\n- Suggesting logical next steps user might want\\n- Structure longer answers with Markdown sections and lists, and put all code, commands, and config in fenced code blocks.\\n\\n**What to include in verbose answers**:\\n- Brief summary of what was done and why\\n- Key files/functions changed (with `file:line` references)\\n- Any important decisions or tradeoffs made\\n- Next steps or things user should verify\\n- Issues found but not fixed\\n\\n**What to avoid**:\\n- Don't show full file contents unless explicitly asked\\n- Don't explain how to save files or copy code (user has access to your work)\\n- Don't use \\\"Here's what I did\\\" or \\\"Let me know if...\\\" style preambles/postambles\\n- Keep tone direct and factual, like handing off work to a teammate\\n</final_answers>\\n\\n<env>\\nWorking directory: /tmp/crush-test/TestCoderAgent/openrouter-kimi-k2/sourcegraph_tool\\nIs directory a git repo: no\\nPlatform: linux\\nToday's date: 1/1/2025\\n\\n</env>\\n\\n\\n\\n\\n\",\"role\":\"system\",\"cache_control\":{\"type\":\"ephemeral\"}},{\"content\":\"<system_reminder>This is a reminder that your todo list is currently empty. DO NOT mention this to the user explicitly because they are already aware.\\nIf you are working on tasks that would benefit from a todo list please use the \\\"todos\\\" tool to create one.\\nIf not, please feel free to ignore. Again do not mention this message to the user.</system_reminder>\",\"role\":\"user\",\"cache_control\":{\"type\":\"ephemeral\"}},{\"content\":\"use sourcegraph to search for 'func main' in Go repositories\",\"role\":\"user\",\"cache_control\":{\"type\":\"ephemeral\"}}],\"model\":\"moonshotai/kimi-k2-0905\",\"max_tokens\":10000,\"stream_options\":{\"include_usage\":true},\"tool_choice\":\"auto\",\"tools\":[{\"function\":{\"name\":\"bash\",\"strict\":false,\"description\":\"Executes bash commands with automatic background conversion for long-running tasks.\\n\\n<cross_platform>\\nUses mvdan/sh interpreter (Bash-compatible on all platforms including Windows).\\nUse forward slashes for paths: \\\"ls C:/foo/bar\\\" not \\\"ls C:\\\\foo\\\\bar\\\".\\nCommon shell builtins and core utils available on Windows.\\n</cross_platform>\\n\\n<execution_steps>\\n1. Directory Verification: If creating directories/files, use LS tool to verify parent exists\\n2. Security Check: Banned commands (alias, aria2c, axel, chrome, curl, curlie, firefox, http-prompt, httpie, links, lynx, nc, safari, scp, ssh, telnet, w3m, wget, xh, doas, su, sudo, apk, apt, apt-cache, apt-get, dnf, dpkg, emerge, home-manager, makepkg, opkg, pacman, paru, pkg, pkg_add, pkg_delete, portage, rpm, yay, yum, zypper, at, batch, chkconfig, crontab, fdisk, mkfs, mount, parted, service, systemctl, umount, firewall-cmd, ifconfig, ip, iptables, netstat, pfctl, route, ufw) return error - explain to user. Safe read-only commands execute without prompts\\n3. Command Execution: Execute with proper quoting, capture output\\n4. Auto-Background: Commands exceeding 1 minute automatically move to background and return shell ID\\n5. Output Processing: Truncate if exceeds 30000 characters\\n6. Return Result: Include errors, metadata with <cwd></cwd> tags\\n</execution_steps>\\n\\n<usage_notes>\\n- Command required, working_dir optional (defaults to current directory)\\n- IMPORTANT: Use Grep/Glob/Agent tools instead of 'find'/'grep'. Use View/LS tools instead of 'cat'/'head'/'tail'/'ls'\\n- Chain with ';' or '&&', avoid newlines except in quoted strings\\n- Each command runs in independent shell (no state persistence between calls)\\n- Prefer absolute paths over 'cd' (use 'cd' only if user explicitly requests)\\n</usage_notes>\\n\\n<background_execution>\\n- Set run_in_background=true to run commands in a separate background shell\\n- Returns a shell ID for managing the background process\\n- Use job_output tool to view current output from background shell\\n- Use job_kill tool to terminate a background shell\\n- IMPORTANT: NEVER use `&` at the end of commands to run in background - use run_in_background parameter instead\\n- Commands that should run in background:\\n * Long-running servers (e.g., `npm start`, `python -m http.server`, `node server.js`)\\n * Watch/monitoring tasks (e.g., `npm run watch`, `tail -f logfile`)\\n * Continuous processes that don't exit on their own\\n * Any command expected to run indefinitely\\n- Commands that should NOT run in background:\\n * Build commands (e.g., `npm run build`, `go build`)\\n * Test suites (e.g., `npm test`, `pytest`)\\n * Git operations\\n * File operations\\n * Short-lived scripts\\n</background_execution>\\n\\n<git_commits>\\nWhen user asks to create git commit:\\n\\n1. Single message with three tool_use blocks (IMPORTANT for speed):\\n - git status (untracked files)\\n - git diff (staged/unstaged changes)\\n - git log (recent commit message style)\\n\\n2. Add relevant untracked files to staging. Don't commit files already modified at conversation start unless relevant.\\n\\n3. Analyze staged changes in <commit_analysis> tags:\\n - List changed/added files, summarize nature (feature/enhancement/bug fix/refactoring/test/docs)\\n - Brainstorm purpose/motivation, assess project impact, check for sensitive info\\n - Don't use tools beyond git context\\n - Draft concise (1-2 sentences) message focusing on \\\"why\\\" not \\\"what\\\"\\n - Use clear language, accurate reflection (\\\"add\\\"=new feature, \\\"update\\\"=enhancement, \\\"fix\\\"=bug fix)\\n - Avoid generic messages, review draft\\n\\n4. Create commit with attribution using HEREDOC:\\n git commit -m \\\"$(cat <<'EOF'\\n Commit message here.\\n\\n\\n \U0001F498 Generated with Crush\\n\\n\\n\\n Co-Authored-By: Crush <crush@charm.land>\\n\\n\\n EOF\\n )\\\"\\n\\n5. If pre-commit hook fails, retry ONCE. If fails again, hook preventing commit. If succeeds but files modified, MUST amend.\\n\\n6. Run git status to verify.\\n\\nNotes: Use \\\"git commit -am\\\" when possible, don't stage unrelated files, NEVER update config, don't push, no -i flags, no empty commits, return empty response.\\n</git_commits>\\n\\n<pull_requests>\\nUse gh command for ALL GitHub tasks. When user asks to create PR:\\n\\n1. Single message with multiple tool_use blocks (VERY IMPORTANT for speed):\\n - git status (untracked files)\\n - git diff (staged/unstaged changes)\\n - Check if branch tracks remote and is up to date\\n - git log and 'git diff main...HEAD' (full commit history from main divergence)\\n\\n2. Create new branch if needed\\n3. Commit changes if needed\\n4. Push to remote with -u flag if needed\\n\\n5. Analyze changes in <pr_analysis> tags:\\n - List commits since diverging from main\\n - Summarize nature of changes\\n - Brainstorm purpose/motivation\\n - Assess project impact\\n - Don't use tools beyond git context\\n - Check for sensitive information\\n - Draft concise (1-2 bullet points) PR summary focusing on \\\"why\\\"\\n - Ensure summary reflects ALL changes since main divergence\\n - Clear, concise language\\n - Accurate reflection of changes and purpose\\n - Avoid generic summaries\\n - Review draft\\n\\n6. Create PR with gh pr create using HEREDOC:\\n gh pr create --title \\\"title\\\" --body \\\"$(cat <<'EOF'\\n\\n ## Summary\\n\\n <1-3 bullet points>\\n\\n ## Test plan\\n\\n [Checklist of TODOs...]\\n\\n\\n \U0001F498 Generated with Crush\\n\\n\\n EOF\\n )\\\"\\n\\nImportant:\\n\\n- Return empty response - user sees gh output\\n- Never update git config\\n</pull_requests>\\n\\n<examples>\\nGood: pytest /foo/bar/tests\\nBad: cd /foo/bar && pytest tests\\n</examples>\\n\",\"parameters\":{\"properties\":{\"command\":{\"description\":\"The command to execute\",\"type\":\"string\"},\"description\":{\"description\":\"A brief description of what the command does, try to keep it under 30 characters or so\",\"type\":\"string\"},\"run_in_background\":{\"description\":\"Set to true (boolean) to run this command in the background. Use job_output to read the output later.\",\"type\":\"boolean\"},\"working_dir\":{\"description\":\"The working directory to execute the command in (defaults to current directory)\",\"type\":\"string\"}},\"required\":[\"description\",\"command\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"download\",\"strict\":false,\"description\":\"Downloads binary data from URL and saves to local file.\\n\\n<usage>\\n- Provide URL to download from\\n- Specify local file path where content should be saved\\n- Optional timeout for request\\n</usage>\\n\\n<features>\\n- Downloads any file type (binary or text)\\n- Auto-creates parent directories if missing\\n- Handles large files efficiently with streaming\\n- Sets reasonable timeouts to prevent hanging\\n- Validates input parameters before requests\\n</features>\\n\\n<limitations>\\n- Max file size: 100MB\\n- Only supports HTTP and HTTPS protocols\\n- Cannot handle authentication or cookies\\n- Some websites may block automated requests\\n- Will overwrite existing files without warning\\n</limitations>\\n\\n<tips>\\n- Use absolute paths or paths relative to working directory\\n- Set appropriate timeouts for large files or slow connections\\n</tips>\\n\",\"parameters\":{\"properties\":{\"file_path\":{\"description\":\"The local file path where the downloaded content should be saved\",\"type\":\"string\"},\"timeout\":{\"description\":\"Optional timeout in seconds (max 600)\",\"type\":\"integer\"},\"url\":{\"description\":\"The URL to download from\",\"type\":\"string\"}},\"required\":[\"url\",\"file_path\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"edit\",\"strict\":false,\"description\":\"Edits files by replacing text, creating new files, or deleting content. For moving/renaming use Bash 'mv'. For large edits use Write tool.\\n\\n<prerequisites>\\n1. Use View tool to understand file contents and context\\n2. For new files: Use LS tool to verify parent directory exists\\n3. **CRITICAL**: Note exact whitespace, indentation, and formatting from View output\\n</prerequisites>\\n\\n<parameters>\\n1. file_path: Absolute path to file (required)\\n2. old_string: Text to replace (must match exactly including whitespace/indentation)\\n3. new_string: Replacement text\\n4. replace_all: Replace all occurrences (default false)\\n</parameters>\\n\\n<special_cases>\\n\\n- Create file: provide file_path + new_string, leave old_string empty\\n- Delete content: provide file_path + old_string, leave new_string empty\\n </special_cases>\\n\\n<critical_requirements>\\nEXACT MATCHING: The tool is extremely literal. Text must match **EXACTLY**\\n\\n- Every space and tab character\\n- Every blank line\\n- Every newline character\\n- Indentation level (count the spaces/tabs)\\n- Comment spacing (`// comment` vs `//comment`)\\n- Brace positioning (`func() {` vs `func(){`)\\n\\nCommon failures:\\n\\n```\\nExpected: \\\" func foo() {\\\" (4 spaces)\\nProvided: \\\" func foo() {\\\" (2 spaces) ❌ FAILS\\n\\nExpected: \\\"}\\\\n\\\\nfunc bar() {\\\" (2 newlines)\\nProvided: \\\"}\\\\nfunc bar() {\\\" (1 newline) ❌ FAILS\\n\\nExpected: \\\"// Comment\\\" (space after //)\\nProvided: \\\"//Comment\\\" (no space) ❌ FAILS\\n```\\n\\nUNIQUENESS (when replace_all=false): old_string MUST uniquely identify target instance\\n\\n- Include 3-5 lines context BEFORE and AFTER change point\\n- Include exact whitespace, indentation, surrounding code\\n- If text appears multiple times, add more context to make it unique\\n\\nSINGLE INSTANCE: Tool changes ONE instance when replace_all=false\\n\\n- For multiple instances: set replace_all=true OR make separate calls with unique context\\n- Plan calls carefully to avoid conflicts\\n\\nVERIFICATION BEFORE USING: Before every edit\\n\\n1. View the file and locate exact target location\\n2. Check how many instances of target text exist\\n3. Copy the EXACT text including all whitespace\\n4. Verify you have enough context for unique identification\\n5. Double-check indentation matches (count spaces/tabs)\\n6. Plan separate calls or use replace_all for multiple changes\\n </critical_requirements>\\n\\n<warnings>\\nTool fails if:\\n- old_string matches multiple locations and replace_all=false\\n- old_string doesn't match exactly (including whitespace)\\n- Insufficient context causes wrong instance change\\n- Indentation is off by even one space\\n- Missing or extra blank lines\\n- Wrong tabs vs spaces\\n</warnings>\\n\\n<recovery_steps>\\nIf you get \\\"old_string not found in file\\\":\\n\\n1. **View the file again** at the specific location\\n2. **Copy more context** - include entire function if needed\\n3. **Check whitespace**:\\n - Count indentation spaces/tabs\\n - Look for blank lines\\n - Check for trailing spaces\\n4. **Verify character-by-character** that your old_string matches\\n5. **Never guess** - always View the file to get exact text\\n </recovery_steps>\\n\\n<best_practices>\\n\\n- Ensure edits result in correct, idiomatic code\\n- Don't leave code in broken state\\n- Use absolute file paths (starting with /)\\n- Use forward slashes (/) for cross-platform compatibility\\n- Multiple edits to same file: send all in single message with multiple tool calls\\n- **When in doubt, include MORE context rather than less**\\n- Match the existing code style exactly (spaces, tabs, blank lines)\\n </best_practices>\\n\\n<whitespace_checklist>\\nBefore submitting an edit, verify:\\n\\n- [ ] Viewed the file first\\n- [ ] Counted indentation spaces/tabs\\n- [ ] Included blank lines if they exist\\n- [ ] Matched brace/bracket positioning\\n- [ ] Included 3-5 lines of surrounding context\\n- [ ] Verified text appears exactly once (or using replace_all)\\n- [ ] Copied text character-for-character, not approximated\\n </whitespace_checklist>\\n\\n<examples>\\n✅ Correct: Exact match with context\\n\\n```\\nold_string: \\\"func ProcessData(input string) error {\\\\n if input == \\\\\\\"\\\\\\\" {\\\\n return errors.New(\\\\\\\"empty input\\\\\\\")\\\\n }\\\\n return nil\\\\n}\\\"\\n\\nnew_string: \\\"func ProcessData(input string) error {\\\\n if input == \\\\\\\"\\\\\\\" {\\\\n return errors.New(\\\\\\\"empty input\\\\\\\")\\\\n }\\\\n // New validation\\\\n if len(input) > 1000 {\\\\n return errors.New(\\\\\\\"input too long\\\\\\\")\\\\n }\\\\n return nil\\\\n}\\\"\\n```\\n\\n❌ Incorrect: Not enough context\\n\\n```\\nold_string: \\\"return nil\\\" // Appears many times!\\n```\\n\\n❌ Incorrect: Wrong indentation\\n\\n```\\nold_string: \\\" if input == \\\\\\\"\\\\\\\" {\\\" // 2 spaces\\n// But file actually has: \\\" if input == \\\\\\\"\\\\\\\" {\\\" // 4 spaces\\n```\\n\\n✅ Correct: Including context to make unique\\n\\n```\\nold_string: \\\"func ProcessData(input string) error {\\\\n if input == \\\\\\\"\\\\\\\" {\\\\n return errors.New(\\\\\\\"empty input\\\\\\\")\\\\n }\\\\n return nil\\\"\\n```\\n\\n</examples>\\n\\n<windows_notes>\\n\\n- Forward slashes work throughout (C:/path/file)\\n- File permissions handled automatically\\n- Line endings converted automatically (\\\\n ↔ \\\\r\\\\n)\\n </windows_notes>\\n\",\"parameters\":{\"properties\":{\"file_path\":{\"description\":\"The absolute path to the file to modify\",\"type\":\"string\"},\"new_string\":{\"description\":\"The text to replace it with\",\"type\":\"string\"},\"old_string\":{\"description\":\"The text to replace\",\"type\":\"string\"},\"replace_all\":{\"description\":\"Replace all occurrences of old_string (default false)\",\"type\":\"boolean\"}},\"required\":[\"file_path\",\"old_string\",\"new_string\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"multiedit\",\"strict\":false,\"description\":\"Makes multiple edits to a single file in one operation. Built on Edit tool for efficient multiple find-and-replace operations. Prefer over Edit tool for multiple edits to same file.\\n\\n<prerequisites>\\n1. Use View tool to understand file contents and context\\n2. Verify directory path is correct\\n3. CRITICAL: Note exact whitespace, indentation, and formatting from View output\\n</prerequisites>\\n\\n<parameters>\\n1. file_path: Absolute path to file (required)\\n2. edits: Array of edit operations, each containing:\\n - old_string: Text to replace (must match exactly including whitespace/indentation)\\n - new_string: Replacement text\\n - replace_all: Replace all occurrences (optional, defaults to false)\\n</parameters>\\n\\n<operation>\\n- Edits applied sequentially in provided order.\\n- Each edit operates on result of previous edit.\\n- PARTIAL SUCCESS: If some edits fail, successful edits are still applied. Failed edits are returned in the response.\\n- File is modified if at least one edit succeeds.\\n- Ideal for several changes to different parts of same file.\\n</operation>\\n\\n<inherited_rules>\\nAll instructions from the Edit tool documentation apply verbatim to every edit item:\\n- Critical requirements for exact matching and uniqueness\\n- Warnings and common failures (tabs vs spaces, blank lines, brace placement, etc.)\\n- Verification steps before using, recovery steps, best practices, and whitespace checklist\\nUse the same level of precision as Edit. Multiedit often fails due to formatting mismatches—double-check whitespace for every edit.\\n</inherited_rules>\\n\\n<critical_requirements>\\n1. Apply Edit tool rules to EACH edit (see edit.md).\\n2. Edits are applied in order; successful edits are kept even if later edits fail.\\n3. Plan sequence carefully: earlier edits change the file content that later edits must match.\\n4. Ensure each old_string is unique at its application time (after prior edits).\\n5. Check the response for failed edits and retry them if needed.\\n</critical_requirements>\\n\\n<verification_before_using>\\n1. View the file and copy exact text (including whitespace) for each target.\\n2. Check how many instances each old_string has BEFORE the sequence starts.\\n3. Dry-run mentally: after applying edit #N, will edit #N+1 still match? Adjust old_string/new_string accordingly.\\n4. Prefer fewer, larger context blocks over many tiny fragments that are easy to misalign.\\n5. If edits are independent, consider separate multiedit batches per logical region.\\n</verification_before_using>\\n\\n<warnings>\\n- Operation continues even if some edits fail; check response for failed edits.\\n- Earlier edits can invalidate later matches (added/removed spaces, lines, or reordered text).\\n- Mixed tabs/spaces, trailing spaces, or missing blank lines commonly cause failures.\\n- replace_all may affect unintended regions—use carefully or provide more context.\\n</warnings>\\n\\n<recovery_steps>\\nIf some edits fail:\\n1. Check the response metadata for the list of failed edits with their error messages.\\n2. View the file again to see the current state after successful edits.\\n3. Adjust the failed edits based on the new file content.\\n4. Retry the failed edits with corrected old_string values.\\n5. Consider breaking complex batches into smaller, independent operations.\\n</recovery_steps>\\n\\n<best_practices>\\n- Ensure all edits result in correct, idiomatic code; don't leave code broken.\\n- Use absolute file paths (starting with /).\\n- Use replace_all only when you're certain; otherwise provide unique context.\\n- Match existing style exactly (spaces, tabs, blank lines).\\n- Review failed edits in the response and retry with corrections.\\n</best_practices>\\n\\n<whitespace_checklist>\\nFor EACH edit, verify:\\n- [ ] Viewed the file first\\n- [ ] Counted indentation spaces/tabs\\n- [ ] Included blank lines if present\\n- [ ] Matched brace/bracket positioning\\n- [ ] Included 3–5 lines of surrounding context\\n- [ ] Verified text appears exactly once (or using replace_all deliberately)\\n- [ ] Copied text character-for-character, not approximated\\n</whitespace_checklist>\\n\\n<examples>\\n✅ Correct: Sequential edits where the second match accounts for the first change\\n\\n```\\nedits: [\\n {\\n old_string: \\\"func A() {\\\\n doOld()\\\\n}\\\",\\n new_string: \\\"func A() {\\\\n doNew()\\\\n}\\\",\\n },\\n {\\n // Uses context that still exists AFTER the first replacement\\n old_string: \\\"func B() {\\\\n callA()\\\\n}\\\",\\n new_string: \\\"func B() {\\\\n callA()\\\\n logChange()\\\\n}\\\",\\n },\\n]\\n```\\n\\n❌ Incorrect: Second old_string no longer matches due to whitespace change introduced by the first edit\\n\\n```\\nedits: [\\n {\\n old_string: \\\"func A() {\\\\n doOld()\\\\n}\\\",\\n new_string: \\\"func A() {\\\\n\\\\n doNew()\\\\n}\\\", // Added extra blank line\\n },\\n {\\n old_string: \\\"func A() {\\\\n doNew()\\\\n}\\\", // Missing the new blank line, will FAIL\\n new_string: \\\"func A() {\\\\n doNew()\\\\n logChange()\\\\n}\\\",\\n },\\n]\\n```\\n\\n✅ Correct: Handling partial success\\n\\n```\\n// If edit 2 fails, edit 1 is still applied\\n// Response will indicate:\\n// - edits_applied: 1\\n// - edits_failed: [{index: 2, error: \\\"...\\\", edit: {...}}]\\n// You can then retry edit 2 with corrected context\\n```\\n</examples>\\n\",\"parameters\":{\"properties\":{\"edits\":{\"description\":\"Array of edit operations to perform sequentially on the file\",\"items\":{\"properties\":{\"new_string\":{\"description\":\"The text to replace it with\",\"type\":\"string\"},\"old_string\":{\"description\":\"The text to replace\",\"type\":\"string\"},\"replace_all\":{\"description\":\"Replace all occurrences of old_string (default false).\",\"type\":\"boolean\"}},\"required\":[\"old_string\",\"new_string\"],\"type\":\"object\"},\"type\":\"array\"},\"file_path\":{\"description\":\"The absolute path to the file to modify\",\"type\":\"string\"}},\"required\":[\"file_path\",\"edits\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"fetch\",\"strict\":false,\"description\":\"Fetches raw content from URL and returns it in specified format without any AI processing.\\n\\n<when_to_use>\\nUse this tool when you need:\\n- Raw, unprocessed content from a URL\\n- Direct access to API responses or JSON data\\n- HTML/text/markdown content without interpretation\\n- Simple, fast content retrieval without analysis\\n- To save tokens by avoiding AI processing\\n\\nDO NOT use this tool when you need to:\\n- Extract specific information from a webpage (use agentic_fetch instead)\\n- Answer questions about web content (use agentic_fetch instead)\\n- Analyze or summarize web pages (use agentic_fetch instead)\\n</when_to_use>\\n\\n<usage>\\n- Provide URL to fetch content from\\n- Specify desired output format (text, markdown, or html)\\n- Optional timeout for request\\n</usage>\\n\\n<features>\\n- Supports three output formats: text, markdown, html\\n- Auto-handles HTTP redirects\\n- Fast and lightweight - no AI processing\\n- Sets reasonable timeouts to prevent hanging\\n- Validates input parameters before requests\\n</features>\\n\\n<limitations>\\n- Max response size: 5MB\\n- Only supports HTTP and HTTPS protocols\\n- Cannot handle authentication or cookies\\n- Some websites may block automated requests\\n- Returns raw content only - no analysis or extraction\\n</limitations>\\n\\n<tips>\\n- Use text format for plain text content or simple API responses\\n- Use markdown format for content that should be rendered with formatting\\n- Use html format when you need raw HTML structure\\n- Set appropriate timeouts for potentially slow websites\\n- If the user asks to analyze or extract from a page, use agentic_fetch instead\\n</tips>\\n\",\"parameters\":{\"properties\":{\"format\":{\"description\":\"The format to return the content in (text, markdown, or html)\",\"type\":\"string\"},\"timeout\":{\"description\":\"Optional timeout in seconds (max 120)\",\"type\":\"integer\"},\"url\":{\"description\":\"The URL to fetch content from\",\"type\":\"string\"}},\"required\":[\"url\",\"format\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"glob\",\"strict\":false,\"description\":\"Fast file pattern matching tool that finds files by name/pattern, returning paths sorted by modification time (newest first).\\n\\n<usage>\\n- Provide glob pattern to match against file paths\\n- Optional starting directory (defaults to current working directory)\\n- Results sorted with most recently modified files first\\n</usage>\\n\\n<pattern_syntax>\\n- '\\\\*' matches any sequence of non-separator characters\\n- '\\\\*\\\\*' matches any sequence including separators\\n- '?' matches any single non-separator character\\n- '[...]' matches any character in brackets\\n- '[!...]' matches any character not in brackets\\n</pattern_syntax>\\n\\n<examples>\\n- '*.js' - JavaScript files in current directory\\n- '**/*.js' - JavaScript files in any subdirectory\\n- 'src/**/*.{ts,tsx}' - TypeScript files in src directory\\n- '*.{html,css,js}' - HTML, CSS, and JS files\\n</examples>\\n\\n<limitations>\\n- Results limited to 100 files (newest first)\\n- Does not search file contents (use Grep for that)\\n- Hidden files (starting with '.') skipped\\n</limitations>\\n\\n<cross_platform>\\n- Path separators handled automatically (/ and \\\\ work)\\n- Uses ripgrep (rg) if available, otherwise Go implementation\\n- Patterns should use forward slashes (/) for compatibility\\n</cross_platform>\\n\\n<tips>\\n- Combine with Grep: find files with Glob, search contents with Grep\\n- For iterative exploration requiring multiple searches, consider Agent tool\\n- Check if results truncated and refine pattern if needed\\n</tips>\\n\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The directory to search in. Defaults to the current working directory.\",\"type\":\"string\"},\"pattern\":{\"description\":\"The glob pattern to match files against\",\"type\":\"string\"}},\"required\":[\"pattern\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"grep\",\"strict\":false,\"description\":\"Fast content search tool that finds files containing specific text/patterns, returning matching paths sorted by modification time (newest first).\\n\\n<usage>\\n- Provide regex pattern to search within file contents\\n- Set literal_text=true for exact text with special characters (recommended for non-regex users)\\n- Optional starting directory (defaults to current working directory)\\n- Optional include pattern to filter which files to search\\n- Results sorted with most recently modified files first\\n</usage>\\n\\n<regex_syntax>\\nWhen literal_text=false (supports standard regex):\\n\\n- 'function' searches for literal text \\\"function\\\"\\n- 'log\\\\..\\\\*Error' finds text starting with \\\"log.\\\" and ending with \\\"Error\\\"\\n- 'import\\\\s+.\\\\*\\\\s+from' finds import statements in JavaScript/TypeScript\\n</regex_syntax>\\n\\n<include_patterns>\\n- '\\\\*.js' - Only search JavaScript files\\n- '\\\\*.{ts,tsx}' - Only search TypeScript files\\n- '\\\\*.go' - Only search Go files\\n</include_patterns>\\n\\n<limitations>\\n- Results limited to 100 files (newest first)\\n- Performance depends on number of files searched\\n- Very large binary files may be skipped\\n- Hidden files (starting with '.') skipped\\n</limitations>\\n\\n<ignore_support>\\n- Respects .gitignore patterns to skip ignored files/directories\\n- Respects .crushignore patterns for additional ignore rules\\n- Both ignore files auto-detected in search root directory\\n</ignore_support>\\n\\n<cross_platform>\\n- Uses ripgrep (rg) if available for better performance\\n- Falls back to Go implementation if ripgrep unavailable\\n- File paths normalized automatically for compatibility\\n</cross_platform>\\n\\n<tips>\\n- For faster searches: use Glob to find relevant files first, then Grep\\n- For iterative exploration requiring multiple searches, consider Agent tool\\n- Check if results truncated and refine search pattern if needed\\n- Use literal_text=true for exact text with special characters (dots, parentheses, etc.)\\n</tips>\\n\",\"parameters\":{\"properties\":{\"include\":{\"description\":\"File pattern to include in the search (e.g. \\\"*.js\\\", \\\"*.{ts,tsx}\\\")\",\"type\":\"string\"},\"literal_text\":{\"description\":\"If true, the pattern will be treated as literal text with special regex characters escaped. Default is false.\",\"type\":\"boolean\"},\"path\":{\"description\":\"The directory to search in. Defaults to the current working directory.\",\"type\":\"string\"},\"pattern\":{\"description\":\"The regex pattern to search for in file contents\",\"type\":\"string\"}},\"required\":[\"pattern\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"ls\",\"strict\":false,\"description\":\"Shows files and subdirectories in tree structure for exploring project organization.\\n\\n<usage>\\n- Provide path to list (defaults to current working directory)\\n- Optional glob patterns to ignore\\n- Results displayed in tree structure\\n</usage>\\n\\n<features>\\n- Hierarchical view of files and directories\\n- Auto-skips hidden files/directories (starting with '.')\\n- Skips common system directories like __pycache__\\n- Can filter files matching specific patterns\\n</features>\\n\\n<limitations>\\n- Results limited to 1000 files\\n- Large directories truncated\\n- No file sizes or permissions shown\\n- Cannot recursively list all directories in large projects\\n</limitations>\\n\\n<cross_platform>\\n- Hidden file detection uses Unix convention (files starting with '.')\\n- Windows hidden files (with hidden attribute) not auto-skipped\\n- Common Windows directories (System32, Program Files) not in default ignore\\n- Path separators handled automatically (/ and \\\\ work)\\n</cross_platform>\\n\\n<tips>\\n- Use Glob for finding files by name patterns instead of browsing\\n- Use Grep for searching file contents\\n- Combine with other tools for effective exploration\\n</tips>\\n\",\"parameters\":{\"properties\":{\"depth\":{\"description\":\"The maximum depth to traverse\",\"type\":\"integer\"},\"ignore\":{\"description\":\"List of glob patterns to ignore\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"path\":{\"description\":\"The path to the directory to list (defaults to current working directory)\",\"type\":\"string\"}},\"required\":[],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"sourcegraph\",\"strict\":false,\"description\":\"Search code across public repositories using Sourcegraph's GraphQL API.\\n\\n<usage>\\n- Provide search query using Sourcegraph syntax\\n- Optional result count (default: 10, max: 20)\\n- Optional timeout for request\\n</usage>\\n\\n<basic_syntax>\\n- \\\"fmt.Println\\\" - exact matches\\n- \\\"file:.go fmt.Println\\\" - limit to Go files\\n- \\\"repo:^github\\\\.com/golang/go$ fmt.Println\\\" - specific repos\\n- \\\"lang:go fmt.Println\\\" - limit to Go code\\n- \\\"fmt.Println AND log.Fatal\\\" - combined terms\\n- \\\"fmt\\\\.(Print|Printf|Println)\\\" - regex patterns\\n- \\\"\\\\\\\"exact phrase\\\\\\\"\\\" - exact phrase matching\\n- \\\"-file:test\\\" or \\\"-repo:forks\\\" - exclude matches\\n</basic_syntax>\\n\\n<key_filters>\\nRepository: repo:name, repo:^exact$, repo:org/repo@branch, -repo:exclude, fork:yes, archived:yes, visibility:public\\nFile: file:\\\\.js$, file:internal/, -file:test, file:has.content(text)\\nContent: content:\\\"exact\\\", -content:\\\"unwanted\\\", case:yes\\nType: type:symbol, type:file, type:path, type:diff, type:commit\\nTime: after:\\\"1 month ago\\\", before:\\\"2023-01-01\\\", author:name, message:\\\"fix\\\"\\nResult: select:repo, select:file, select:content, count:100, timeout:30s\\n</key_filters>\\n\\n<examples>\\n- \\\"file:.go context.WithTimeout\\\" - Go code using context.WithTimeout\\n- \\\"lang:typescript useState type:symbol\\\" - TypeScript React useState hooks\\n- \\\"repo:^github\\\\.com/kubernetes/kubernetes$ pod list type:file\\\" - Kubernetes pod files\\n- \\\"file:Dockerfile (alpine OR ubuntu) -content:alpine:latest\\\" - Dockerfiles with base images\\n</examples>\\n\\n<boolean_operators>\\n- \\\"term1 AND term2\\\" - both terms\\n- \\\"term1 OR term2\\\" - either term\\n- \\\"term1 NOT term2\\\" - term1 but not term2\\n- \\\"term1 and (term2 or term3)\\\" - grouping with parentheses\\n</boolean_operators>\\n\\n<limitations>\\n- Only searches public repositories\\n- Rate limits may apply\\n- Complex queries take longer\\n- Max 20 results per query\\n</limitations>\\n\\n<tips>\\n- Use specific file extensions to narrow results\\n- Add repo: filters for targeted searches\\n- Use type:symbol for function/method definitions\\n- Use type:file to find relevant files\\n</tips>\\n\",\"parameters\":{\"properties\":{\"context_window\":{\"description\":\"The context around the match to return (default: 10 lines)\",\"type\":\"integer\"},\"count\":{\"description\":\"Optional number of results to return (default: 10, max: 20)\",\"type\":\"integer\"},\"query\":{\"description\":\"The Sourcegraph search query\",\"type\":\"string\"},\"timeout\":{\"description\":\"Optional timeout in seconds (max 120)\",\"type\":\"integer\"}},\"required\":[\"query\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"view\",\"strict\":false,\"description\":\"Reads and displays file contents with line numbers for examining code, logs, or text data.\\n\\n<usage>\\n- Provide file path to read\\n- Optional offset: start reading from specific line (0-based)\\n- Optional limit: control lines read (default 2000)\\n- Don't use for directories (use LS tool instead)\\n- Supports image files (PNG, JPEG, GIF, BMP, SVG, WebP)\\n</usage>\\n\\n<features>\\n- Displays contents with line numbers\\n- Can read from any file position using offset\\n- Handles large files by limiting lines read\\n- Auto-truncates very long lines for display\\n- Suggests similar filenames when file not found\\n- Renders image files directly in terminal\\n</features>\\n\\n<limitations>\\n- Max file size: 5MB\\n- Default limit: 2000 lines\\n- Lines >2000 chars truncated\\n- Binary files (except images) cannot be displayed\\n</limitations>\\n\\n<cross_platform>\\n- Handles Windows (CRLF) and Unix (LF) line endings\\n- Works with forward slashes (/) and backslashes (\\\\)\\n- Auto-detects text encoding for common formats\\n</cross_platform>\\n\\n<tips>\\n- Use with Glob to find files first\\n- For code exploration: Grep to find relevant files, then View to examine\\n- For large files: use offset parameter for specific sections\\n- View tool automatically detects and renders image files\\n</tips>\\n\",\"parameters\":{\"properties\":{\"file_path\":{\"description\":\"The path to the file to read\",\"type\":\"string\"},\"limit\":{\"description\":\"The number of lines to read (defaults to 2000)\",\"type\":\"integer\"},\"offset\":{\"description\":\"The line number to start reading from (0-based)\",\"type\":\"integer\"}},\"required\":[\"file_path\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"write\",\"strict\":false,\"description\":\"Creates or updates files in filesystem for saving/modifying text content.\\n\\n<usage>\\n- Provide file path to write\\n- Include content to write to file\\n- Tool creates necessary parent directories automatically\\n</usage>\\n\\n<features>\\n- Creates new files or overwrites existing ones\\n- Auto-creates parent directories if missing\\n- Checks if file modified since last read for safety\\n- Avoids unnecessary writes when content unchanged\\n</features>\\n\\n<limitations>\\n- Read file before writing to avoid conflicts\\n- Cannot append (rewrites entire file)\\n</limitations>\\n\\n<cross_platform>\\n- Use forward slashes (/) for compatibility\\n</cross_platform>\\n\\n<tips>\\n- Use View tool first to examine existing files before modifying\\n- Use LS tool to verify location when creating new files\\n- Combine with Glob/Grep to find and modify multiple files\\n- Include descriptive comments when changing existing code\\n</tips>\\n\",\"parameters\":{\"properties\":{\"content\":{\"description\":\"The content to write to the file\",\"type\":\"string\"},\"file_path\":{\"description\":\"The path to the file to write\",\"type\":\"string\"}},\"required\":[\"file_path\",\"content\"],\"type\":\"object\"}},\"type\":\"function\"}],\"usage\":{\"include\":true},\"stream\":true}"
12 headers:
13 Accept:
14 - application/json
15 Content-Type:
16 - application/json
17 User-Agent:
18 - OpenAI/Go 2.7.1
19 url: https://openrouter.ai/api/v1/chat/completions
20 method: POST
21 response:
22 proto: HTTP/2.0
23 proto_major: 2
24 proto_minor: 0
25 content_length: -1
26 body: |+
27 data: {"id":"gen-1773004268-88jfllWeYQYekJ2tbJVf","object":"chat.completion.chunk","created":1773004268,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":null,"role":"assistant","tool_calls":[{"index":0,"id":"functions.sourcegraph:0","type":"function","function":{"name":"sourcegraph","arguments":""}}]},"finish_reason":null,"native_finish_reason":null}]}
28
29 data: {"id":"gen-1773004268-88jfllWeYQYekJ2tbJVf","object":"chat.completion.chunk","created":1773004268,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":null,"role":"assistant","tool_calls":[{"index":0,"function":{"arguments":"{\"query\": \"func main lang:go\"}"}}]},"finish_reason":null,"native_finish_reason":null}]}
30
31 data: {"id":"gen-1773004268-88jfllWeYQYekJ2tbJVf","object":"chat.completion.chunk","created":1773004268,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"","role":"assistant"},"finish_reason":"tool_calls","native_finish_reason":"tool_calls"}]}
32
33 data: {"id":"gen-1773004268-88jfllWeYQYekJ2tbJVf","object":"chat.completion.chunk","created":1773004268,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[],"usage":{"prompt_tokens":11657,"completion_tokens":20,"total_tokens":11677,"cost":0.0018228,"is_byok":false,"prompt_tokens_details":{"cached_tokens":11520,"cache_write_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0018228,"upstream_inference_prompt_cost":0.0017828,"upstream_inference_completions_cost":0.00004},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}
34
35 data: [DONE]
36
37 headers:
38 Content-Type:
39 - text/event-stream
40 status: 200 OK
41 code: 200
42 duration: 759.43325ms
43- id: 1
44 request:
45 proto: HTTP/1.1
46 proto_major: 1
47 proto_minor: 1
48 content_length: 769
49 host: ""
50 body: '{"messages":[{"content":"you will generate a short title based on the first message a user begins a conversation with\n\n<rules>\n- ensure it is not more than 50 characters long\n- the title should be a summary of the user''s message\n- it should be one line long\n- do not use quotes or colons\n- the entire text you return will be used as the title\n- never return anything that is more than one sentence (one line) long\n</rules>\n\n /no_think","role":"system"},{"content":"Generate a concise title for the following content:\n\nuse sourcegraph to search for ''func main'' in Go repositories\n <think>\n\n</think>","role":"user"}],"model":"qwen/qwen3-next-80b-a3b-instruct","max_tokens":40,"stream_options":{"include_usage":true},"usage":{"include":true},"stream":true}'
51 headers:
52 Accept:
53 - application/json
54 Content-Type:
55 - application/json
56 User-Agent:
57 - OpenAI/Go 2.7.1
58 url: https://openrouter.ai/api/v1/chat/completions
59 method: POST
60 response:
61 proto: HTTP/2.0
62 proto_major: 2
63 proto_minor: 0
64 content_length: -1
65 body: |+
66 data: {"id":"gen-1773004268-9tQOvw7EtUdBRXDjICIT","object":"chat.completion.chunk","created":1773004268,"model":"qwen/qwen3-next-80b-a3b-instruct-2509","provider":"Parasail","choices":[{"index":0,"delta":{"content":"Search","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
67
68 data: {"id":"gen-1773004268-9tQOvw7EtUdBRXDjICIT","object":"chat.completion.chunk","created":1773004268,"model":"qwen/qwen3-next-80b-a3b-instruct-2509","provider":"Parasail","choices":[{"index":0,"delta":{"content":" for","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
69
70 data: {"id":"gen-1773004268-9tQOvw7EtUdBRXDjICIT","object":"chat.completion.chunk","created":1773004268,"model":"qwen/qwen3-next-80b-a3b-instruct-2509","provider":"Parasail","choices":[{"index":0,"delta":{"content":" func","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
71
72 data: {"id":"gen-1773004268-9tQOvw7EtUdBRXDjICIT","object":"chat.completion.chunk","created":1773004268,"model":"qwen/qwen3-next-80b-a3b-instruct-2509","provider":"Parasail","choices":[{"index":0,"delta":{"content":" main","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
73
74 data: {"id":"gen-1773004268-9tQOvw7EtUdBRXDjICIT","object":"chat.completion.chunk","created":1773004268,"model":"qwen/qwen3-next-80b-a3b-instruct-2509","provider":"Parasail","choices":[{"index":0,"delta":{"content":" in","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
75
76 data: {"id":"gen-1773004268-9tQOvw7EtUdBRXDjICIT","object":"chat.completion.chunk","created":1773004268,"model":"qwen/qwen3-next-80b-a3b-instruct-2509","provider":"Parasail","choices":[{"index":0,"delta":{"content":" Go","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
77
78 data: {"id":"gen-1773004268-9tQOvw7EtUdBRXDjICIT","object":"chat.completion.chunk","created":1773004268,"model":"qwen/qwen3-next-80b-a3b-instruct-2509","provider":"Parasail","choices":[{"index":0,"delta":{"content":" repositories","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
79
80 data: {"id":"gen-1773004268-9tQOvw7EtUdBRXDjICIT","object":"chat.completion.chunk","created":1773004268,"model":"qwen/qwen3-next-80b-a3b-instruct-2509","provider":"Parasail","choices":[{"index":0,"delta":{"content":" using","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
81
82 data: {"id":"gen-1773004268-9tQOvw7EtUdBRXDjICIT","object":"chat.completion.chunk","created":1773004268,"model":"qwen/qwen3-next-80b-a3b-instruct-2509","provider":"Parasail","choices":[{"index":0,"delta":{"content":" Source","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
83
84 data: {"id":"gen-1773004268-9tQOvw7EtUdBRXDjICIT","object":"chat.completion.chunk","created":1773004268,"model":"qwen/qwen3-next-80b-a3b-instruct-2509","provider":"Parasail","choices":[{"index":0,"delta":{"content":"graph","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
85
86 data: {"id":"gen-1773004268-9tQOvw7EtUdBRXDjICIT","object":"chat.completion.chunk","created":1773004268,"model":"qwen/qwen3-next-80b-a3b-instruct-2509","provider":"Parasail","choices":[{"index":0,"delta":{"content":"","role":"assistant"},"finish_reason":"stop","native_finish_reason":"stop"}]}
87
88 data: {"id":"gen-1773004268-9tQOvw7EtUdBRXDjICIT","object":"chat.completion.chunk","created":1773004268,"model":"qwen/qwen3-next-80b-a3b-instruct-2509","provider":"Parasail","choices":[],"usage":{"prompt_tokens":140,"completion_tokens":11,"total_tokens":151,"cost":0.0000261,"is_byok":false,"prompt_tokens_details":{"cached_tokens":0,"cache_write_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0000261,"upstream_inference_prompt_cost":0.000014,"upstream_inference_completions_cost":0.0000121},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}
89
90 data: [DONE]
91
92 headers:
93 Content-Type:
94 - text/event-stream
95 status: 200 OK
96 code: 200
97 duration: 1.991380792s
98- id: 2
99 request:
100 proto: HTTP/1.1
101 proto_major: 1
102 proto_minor: 1
103 content_length: 424
104 host: sourcegraph.com
105 body: '{"query":"query Search($query: String!) { search(query: $query, version: V2, patternType: keyword ) { results { matchCount, limitHit, resultCount, approximateResultCount, missing { name }, timedout { name }, indexUnavailable, results { __typename, ... on FileMatch { repository { name }, file { path, url, content }, lineMatches { preview, lineNumber, offsetAndLengths } } } } } }","variables":{"query":"func main lang:go"}}'
106 headers:
107 Content-Type:
108 - application/json
109 User-Agent:
110 - crush/1.0
111 url: https://sourcegraph.com/.api/graphql
112 method: POST
113 response:
114 proto: HTTP/2.0
115 proto_major: 2
116 proto_minor: 0
117 content_length: -1
118 uncompressed: true
119 body: '{"data":{"search":{"results":{"matchCount":30,"limitHit":true,"resultCount":30,"approximateResultCount":"30+","missing":[],"timedout":[],"indexUnavailable":false,"results":[{"__typename":"FileMatch","repository":{"name":"github.com/Balun-courses/deep_go"},"file":{"path":"lessons/functions/defer_with_function/main.go","url":"/r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/defer_with_function/main.go","content":"package main\n\nimport \"fmt\"\n\nfunc get() string {\n\tfmt.Println(\"1\")\n\treturn \"\"\n}\n\nfunc handle(string) {\n\tfmt.Println(\"3\")\n}\n\nfunc process() {\n\tdefer handle(get())\n\tfmt.Println(\"2\")\n}\n\nfunc main() {\n\tprocess()\n}\n"},"lineMatches":[{"preview":"func main() {","lineNumber":18,"offsetAndLengths":[[0,9]]},{"preview":"package main","lineNumber":0,"offsetAndLengths":[[8,4]]},{"preview":"func process() {","lineNumber":13,"offsetAndLengths":[[0,4]]},{"preview":"func get() string {","lineNumber":4,"offsetAndLengths":[[0,4]]},{"preview":"func handle(string) {","lineNumber":9,"offsetAndLengths":[[0,4]]}]},{"__typename":"FileMatch","repository":{"name":"github.com/Balun-courses/deep_go"},"file":{"path":"lessons/functions/high_order_function/main.go","url":"/r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/high_order_function/main.go","content":"package main\n\nimport \"fmt\"\n\nfunc forEach(data []int, fn func(int) int) []int {\n\tnewData := make([]int, 0, len(data))\n\tfor _, value := range data {\n\t\tnewData = append(newData, fn(value))\n\t}\n\n\treturn newData\n}\n\nfunc main() {\n\tvar data = []int{1, 2, 3, 4}\n\tvar newData = forEach(data, func(value int) int {\n\t\treturn (value * value)\n\t})\n\n\tfmt.Println(data)\n\tfmt.Println(newData)\n}\n"},"lineMatches":[{"preview":"func main() {","lineNumber":13,"offsetAndLengths":[[0,9]]},{"preview":"\tvar newData = forEach(data, func(value int) int {","lineNumber":15,"offsetAndLengths":[[29,4]]},{"preview":"package main","lineNumber":0,"offsetAndLengths":[[8,4]]},{"preview":"func forEach(data []int, fn func(int) int) []int {","lineNumber":4,"offsetAndLengths":[[0,4],[28,4]]}]},{"__typename":"FileMatch","repository":{"name":"github.com/Balun-courses/deep_go"},"file":{"path":"lessons/functions/composition/main.go","url":"/r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/composition/main.go","content":"package main\n\nimport \"fmt\"\n\nfunc sqr(number int) int {\n\treturn number * number\n}\n\nfunc neg(number int) int {\n\treturn -number\n}\n\nfunc compose(fn ...func(int) int) func(int) int {\n\treturn func(value int) int {\n\t\tfor _, v := range fn {\n\t\t\tvalue = v(value)\n\t\t}\n\n\t\treturn value\n\t}\n}\n\nfunc main() {\n\tfn := compose(sqr, neg, sqr)\n\tfmt.Println(fn(4))\n}\n"},"lineMatches":[{"preview":"func main() {","lineNumber":22,"offsetAndLengths":[[0,9]]},{"preview":"package main","lineNumber":0,"offsetAndLengths":[[8,4]]},{"preview":"func compose(fn ...func(int) int) func(int) int {","lineNumber":12,"offsetAndLengths":[[0,4],[19,4],[34,4]]},{"preview":"\treturn func(value int) int {","lineNumber":13,"offsetAndLengths":[[8,4]]},{"preview":"func sqr(number int) int {","lineNumber":4,"offsetAndLengths":[[0,4]]},{"preview":"func neg(number int) int {","lineNumber":8,"offsetAndLengths":[[0,4]]}]},{"__typename":"FileMatch","repository":{"name":"github.com/Balun-courses/deep_go"},"file":{"path":"lessons/functions/defer_evaluation_moment/main.go","url":"/r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/defer_evaluation_moment/main.go","content":"package main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar f func()\n\tdefer f()\n\n\tf = func() {\n\t\tfmt.Println(true)\n\t}\n}\n"},"lineMatches":[{"preview":"func main() {","lineNumber":4,"offsetAndLengths":[[0,9]]},{"preview":"\tvar f func()","lineNumber":5,"offsetAndLengths":[[7,4]]},{"preview":"package main","lineNumber":0,"offsetAndLengths":[[8,4]]},{"preview":"\tf = func() {","lineNumber":8,"offsetAndLengths":[[5,4]]}]},{"__typename":"FileMatch","repository":{"name":"github.com/Balun-courses/deep_go"},"file":{"path":"lessons/contexts/after_done/main.go","url":"/r/github.com/Balun-courses/deep_go/-/blob/lessons/contexts/after_done/main.go","content":"package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n)\n\n// context.AfterFunc\n\nfunc WithCtxAfterFunc(ctx context.Context, action func()) {\n\tif action != nil {\n\t\tgo func() {\n\t\t\t\u003c-ctx.Done()\n\t\t\taction()\n\t\t}()\n\t}\n}\n\nfunc main() {\n\tctx, cancel := context.WithCancel(context.Background())\n\tWithCtxAfterFunc(ctx, func() {\n\t\tfmt.Println(\"after\")\n\t})\n\n\tcancel()\n\n\ttime.Sleep(100 * time.Millisecond)\n}\n"},"lineMatches":[{"preview":"func main() {","lineNumber":19,"offsetAndLengths":[[0,9]]},{"preview":"\tWithCtxAfterFunc(ctx, func() {","lineNumber":21,"offsetAndLengths":[[13,4],[23,4]]},{"preview":"package main","lineNumber":0,"offsetAndLengths":[[8,4]]},{"preview":"// context.AfterFunc","lineNumber":8,"offsetAndLengths":[[16,4]]},{"preview":"func WithCtxAfterFunc(ctx context.Context, action func()) {","lineNumber":10,"offsetAndLengths":[[0,4],[17,4],[50,4]]}]}]}}}}'
120 headers:
121 Content-Type:
122 - application/json
123 status: 200 OK
124 code: 200
125 duration: 30.407616667s
126- id: 3
127 request:
128 proto: HTTP/1.1
129 proto_major: 1
130 proto_minor: 1
131 content_length: 59776
132 host: ""
133 body: "{\"messages\":[{\"content\":\"You are Crush, a powerful AI Assistant that runs in the CLI.\\n\\n<critical_rules>\\nThese rules override everything else. Follow them strictly:\\n\\n1. **READ BEFORE EDITING**: Never edit a file you haven't already read in this conversation. Once read, you don't need to re-read unless it changed. Pay close attention to exact formatting, indentation, and whitespace - these must match exactly in your edits.\\n2. **BE AUTONOMOUS**: Don't ask questions - search, read, think, decide, act. Break complex tasks into steps and complete them all. Systematically try alternative strategies (different commands, search terms, tools, refactors, or scopes) until either the task is complete or you hit a hard external limit (missing credentials, permissions, files, or network access you cannot change). Only stop for actual blocking errors, not perceived difficulty.\\n3. **TEST AFTER CHANGES**: Run tests immediately after each modification.\\n4. **BE CONCISE**: Keep output concise (default <4 lines), unless explaining complex changes or asked for detail. Conciseness applies to output only, not to thoroughness of work.\\n5. **USE EXACT MATCHES**: When editing, match text exactly including whitespace, indentation, and line breaks.\\n6. **NEVER COMMIT**: Unless user explicitly says \\\"commit\\\".\\n7. **FOLLOW MEMORY FILE INSTRUCTIONS**: If memory files contain specific instructions, preferences, or commands, you MUST follow them.\\n8. **NEVER ADD COMMENTS**: Only add comments if the user asked you to do so. Focus on *why* not *what*. NEVER communicate with the user through code comments.\\n9. **SECURITY FIRST**: Only assist with defensive security tasks. Refuse to create, modify, or improve code that may be used maliciously.\\n10. **NO URL GUESSING**: Only use URLs provided by the user or found in local files.\\n11. **NEVER PUSH TO REMOTE**: Don't push changes to remote repositories unless explicitly asked.\\n12. **DON'T REVERT CHANGES**: Don't revert changes unless they caused errors or the user explicitly asks.\\n13. **TOOL CONSTRAINTS**: Only use documented tools. Never attempt 'apply_patch' or 'apply_diff' - they don't exist. Use 'edit' or 'multiedit' instead.\\n</critical_rules>\\n\\n<communication_style>\\nKeep responses minimal:\\n- Under 4 lines of text (tool use doesn't count)\\n- Conciseness is about **text only**: always fully implement the requested feature, tests, and wiring even if that requires many tool calls.\\n- No preamble (\\\"Here's...\\\", \\\"I'll...\\\")\\n- No postamble (\\\"Let me know...\\\", \\\"Hope this helps...\\\")\\n- One-word answers when possible\\n- No emojis ever\\n- No explanations unless user asks\\n- Never send acknowledgement-only responses; after receiving new context or instructions, immediately continue the task or state the concrete next action you will take.\\n- Use rich Markdown formatting (headings, bullet lists, tables, code fences) for any multi-sentence or explanatory answer; only use plain unformatted text if the user explicitly asks.\\n- Respond ALL sentenses in the same spoken language the prompt was written in.\\n\\nExamples:\\nuser: what is 2+2?\\nassistant: 4\\n\\nuser: list files in src/\\nassistant: [uses ls tool]\\nfoo.c, bar.c, baz.c\\n\\nuser: which file has the foo implementation?\\nassistant: src/foo.c\\n\\nuser: add error handling to the login function\\nassistant: [searches for login, reads file, edits with exact match, runs tests]\\nDone\\n\\nuser: Where are errors from the client handled?\\nassistant: Clients are marked as failed in the `connectToServer` function in src/services/process.go:712.\\n</communication_style>\\n\\n<code_references>\\nWhen referencing specific functions or code locations, use the pattern `file_path:line_number` to help users navigate:\\n- Example: \\\"The error is handled in src/main.go:45\\\"\\n- Example: \\\"See the implementation in pkg/utils/helper.go:123-145\\\"\\n</code_references>\\n\\n<workflow>\\nFor every task, follow this sequence internally (don't narrate it):\\n\\n**Before acting**:\\n- Search codebase for relevant files\\n- Read files to understand current state\\n- Check memory for stored commands\\n- Identify what needs to change\\n- Use `git log` and `git blame` for additional context when needed\\n\\n**While acting**:\\n- Read entire file before editing it\\n- Before editing: verify exact whitespace and indentation from View output\\n- Use exact text for find/replace (include whitespace)\\n- Make one logical change at a time\\n- After each change: run tests\\n- If tests fail: fix immediately\\n- If edit fails: read more context, don't guess - the text must match exactly\\n- Keep going until query is completely resolved before yielding to user\\n- For longer tasks, send brief progress updates (under 10 words) BUT IMMEDIATELY CONTINUE WORKING - progress updates are not stopping points\\n\\n**Before finishing**:\\n- Verify ENTIRE query is resolved (not just first step)\\n- All described next steps must be completed\\n- Cross-check the original prompt and your own mental checklist; if any feasible part remains undone, continue working instead of responding.\\n- Run lint/typecheck if in memory\\n- Verify all changes work\\n- Keep response under 4 lines\\n\\n**Key behaviors**:\\n- Use find_references before changing shared code\\n- Follow existing patterns (check similar files)\\n- If stuck, try different approach (don't repeat failures)\\n- Make decisions yourself (search first, don't ask)\\n- Fix problems at root cause, not surface-level patches\\n- Don't fix unrelated bugs or broken tests (mention them in final message if relevant)\\n</workflow>\\n\\n<decision_making>\\n**Make decisions autonomously** - don't ask when you can:\\n- Search to find the answer\\n- Read files to see patterns\\n- Check similar code\\n- Infer from context\\n- Try most likely approach\\n- When requirements are underspecified but not obviously dangerous, make the most reasonable assumptions based on project patterns and memory files, briefly state them if needed, and proceed instead of waiting for clarification.\\n\\n**Only stop/ask user if**:\\n- Truly ambiguous business requirement\\n- Multiple valid approaches with big tradeoffs\\n- Could cause data loss\\n- Exhausted all attempts and hit actual blocking errors\\n\\n**When requesting information/access**:\\n- Exhaust all available tools, searches, and reasonable assumptions first.\\n- Never say \\\"Need more info\\\" without detail.\\n- In the same message, list each missing item, why it is required, acceptable substitutes, and what you already attempted.\\n- State exactly what you will do once the information arrives so the user knows the next step.\\n\\nWhen you must stop, first finish all unblocked parts of the request, then clearly report: (a) what you tried, (b) exactly why you are blocked, and (c) the minimal external action required. Don't stop just because one path failed—exhaust multiple plausible approaches first.\\n\\n**Never stop for**:\\n- Task seems too large (break it down)\\n- Multiple files to change (change them)\\n- Concerns about \\\"session limits\\\" (no such limits exist)\\n- Work will take many steps (do all the steps)\\n\\nExamples of autonomous decisions:\\n- File location → search for similar files\\n- Test command → check package.json/memory\\n- Code style → read existing code\\n- Library choice → check what's used\\n- Naming → follow existing names\\n</decision_making>\\n\\n<editing_files>\\n**Available edit tools:**\\n- `edit` - Single find/replace in a file\\n- `multiedit` - Multiple find/replace operations in one file\\n- `write` - Create/overwrite entire file\\n\\nNever use `apply_patch` or similar - those tools don't exist.\\n\\nCritical: ALWAYS read files before editing them in this conversation.\\n\\nWhen using edit tools:\\n1. Read the file first - note the EXACT indentation (spaces vs tabs, count)\\n2. Copy the exact text including ALL whitespace, newlines, and indentation\\n3. Include 3-5 lines of context before and after the target\\n4. Verify your old_string would appear exactly once in the file\\n5. If uncertain about whitespace, include more surrounding context\\n6. Verify edit succeeded\\n7. Run tests\\n\\n**Whitespace matters**:\\n- Count spaces/tabs carefully (use View tool line numbers as reference)\\n- Include blank lines if they exist\\n- Match line endings exactly\\n- When in doubt, include MORE context rather than less\\n\\nEfficiency tips:\\n- Don't re-read files after successful edits (tool will fail if it didn't work)\\n- Same applies for making folders, deleting files, etc.\\n\\nCommon mistakes to avoid:\\n- Editing without reading first\\n- Approximate text matches\\n- Wrong indentation (spaces vs tabs, wrong count)\\n- Missing or extra blank lines\\n- Not enough context (text appears multiple times)\\n- Trimming whitespace that exists in the original\\n- Not testing after changes\\n</editing_files>\\n\\n<whitespace_and_exact_matching>\\nThe Edit tool is extremely literal. \\\"Close enough\\\" will fail.\\n\\n**Before every edit**:\\n1. View the file and locate the exact lines to change\\n2. Copy the text EXACTLY including:\\n - Every space and tab\\n - Every blank line\\n - Opening/closing braces position\\n - Comment formatting\\n3. Include enough surrounding lines (3-5) to make it unique\\n4. Double-check indentation level matches\\n\\n**Common failures**:\\n- `func foo() {` vs `func foo(){` (space before brace)\\n- Tab vs 4 spaces vs 2 spaces\\n- Missing blank line before/after\\n- `// comment` vs `//comment` (space after //)\\n- Different number of spaces in indentation\\n\\n**If edit fails**:\\n- View the file again at the specific location\\n- Copy even more context\\n- Check for tabs vs spaces\\n- Verify line endings\\n- Try including the entire function/block if needed\\n- Never retry with guessed changes - get the exact text first\\n</whitespace_and_exact_matching>\\n\\n<task_completion>\\nEnsure every task is implemented completely, not partially or sketched.\\n\\n1. **Think before acting** (for non-trivial tasks)\\n - Identify all components that need changes (models, logic, routes, config, tests, docs)\\n - Consider edge cases and error paths upfront\\n - Form a mental checklist of requirements before making the first edit\\n - This planning happens internally - don't narrate it to the user\\n\\n2. **Implement end-to-end**\\n - Treat every request as complete work: if adding a feature, wire it fully\\n - Update all affected files (callers, configs, tests, docs)\\n - Don't leave TODOs or \\\"you'll also need to...\\\" - do it yourself\\n - No task is too large - break it down and complete all parts\\n - For multi-part prompts, treat each bullet/question as a checklist item and ensure every item is implemented or answered. Partial completion is not an acceptable final state.\\n\\n3. **Verify before finishing**\\n - Re-read the original request and verify each requirement is met\\n - Check for missing error handling, edge cases, or unwired code\\n - Run tests to confirm the implementation works\\n - Only say \\\"Done\\\" when truly done - never stop mid-task\\n</task_completion>\\n\\n<error_handling>\\nWhen errors occur:\\n1. Read complete error message\\n2. Understand root cause (isolate with debug logs or minimal reproduction if needed)\\n3. Try different approach (don't repeat same action)\\n4. Search for similar code that works\\n5. Make targeted fix\\n6. Test to verify\\n7. For each error, attempt at least two or three distinct remediation strategies (search similar code, adjust commands, narrow or widen scope, change approach) before concluding the problem is externally blocked.\\n\\nCommon errors:\\n- Import/Module → check paths, spelling, what exists\\n- Syntax → check brackets, indentation, typos\\n- Tests fail → read test, see what it expects\\n- File not found → use ls, check exact path\\n\\n**Edit tool \\\"old_string not found\\\"**:\\n- View the file again at the target location\\n- Copy the EXACT text including all whitespace\\n- Include more surrounding context (full function if needed)\\n- Check for tabs vs spaces, extra/missing blank lines\\n- Count indentation spaces carefully\\n- Don't retry with approximate matches - get the exact text\\n</error_handling>\\n\\n<memory_instructions>\\nMemory files store commands, preferences, and codebase info. Update them when you discover:\\n- Build/test/lint commands\\n- Code style preferences\\n- Important codebase patterns\\n- Useful project information\\n</memory_instructions>\\n\\n<code_conventions>\\nBefore writing code:\\n1. Check if library exists (look at imports, package.json)\\n2. Read similar code for patterns\\n3. Match existing style\\n4. Use same libraries/frameworks\\n5. Follow security best practices (never log secrets)\\n6. Don't use one-letter variable names unless requested\\n\\nNever assume libraries are available - verify first.\\n\\n**Ambition vs. precision**:\\n- New projects → be creative and ambitious with implementation\\n- Existing codebases → be surgical and precise, respect surrounding code\\n- Don't change filenames or variables unnecessarily\\n- Don't add formatters/linters/tests to codebases that don't have them\\n</code_conventions>\\n\\n<testing>\\nAfter significant changes:\\n- Start testing as specific as possible to code changed, then broaden to build confidence\\n- Use self-verification: write unit tests, add output logs, or use debug statements to verify your solutions\\n- Run relevant test suite\\n- If tests fail, fix before continuing\\n- Check memory for test commands\\n- Run lint/typecheck if available (on precise targets when possible)\\n- For formatters: iterate max 3 times to get it right; if still failing, present correct solution and note formatting issue\\n- Suggest adding commands to memory if not found\\n- Don't fix unrelated bugs or test failures (not your responsibility)\\n</testing>\\n\\n<tool_usage>\\n- Default to using tools (ls, grep, view, agent, tests, web_fetch, etc.) rather than speculation whenever they can reduce uncertainty or unlock progress, even if it takes multiple tool calls.\\n- Search before assuming\\n- Read files before editing\\n- Always use absolute paths for file operations (editing, reading, writing)\\n- Use Agent tool for complex searches\\n- Run tools in parallel when safe (no dependencies)\\n- When making multiple independent bash calls, send them in a single message with multiple tool calls for parallel execution\\n- Summarize tool output for user (they don't see it)\\n- Never use `curl` through the bash tool it is not allowed use the fetch tool instead.\\n- Only use the tools you know exist.\\n\\n<bash_commands>\\n**CRITICAL**: The `description` parameter is REQUIRED for all bash tool calls. Always provide it.\\n\\nWhen running non-trivial bash commands (especially those that modify the system):\\n- Briefly explain what the command does and why you're running it\\n- This ensures the user understands potentially dangerous operations\\n- Simple read-only commands (ls, cat, etc.) don't need explanation\\n- Use `&` for background processes that won't stop on their own (e.g., `node server.js &`)\\n- Avoid interactive commands - use non-interactive versions (e.g., `npm init -y` not `npm init`)\\n- Combine related commands to save time (e.g., `git status && git diff HEAD && git log -n 3`)\\n</bash_commands>\\n</tool_usage>\\n\\n<proactiveness>\\nBalance autonomy with user intent:\\n- When asked to do something → do it fully (including ALL follow-ups and \\\"next steps\\\")\\n- Never describe what you'll do next - just do it\\n- When the user provides new information or clarification, incorporate it immediately and keep executing instead of stopping with an acknowledgement.\\n- Responding with only a plan, outline, or TODO list (or any other purely verbal response) is failure; you must execute the plan via tools whenever execution is possible.\\n- When asked how to approach → explain first, don't auto-implement\\n- After completing work → stop, don't explain (unless asked)\\n- Don't surprise user with unexpected actions\\n</proactiveness>\\n\\n<final_answers>\\nAdapt verbosity to match the work completed:\\n\\n**Default (under 4 lines)**:\\n- Simple questions or single-file changes\\n- Casual conversation, greetings, acknowledgements\\n- One-word answers when possible\\n\\n**More detail allowed (up to 10-15 lines)**:\\n- Large multi-file changes that need walkthrough\\n- Complex refactoring where rationale adds value\\n- Tasks where understanding the approach is important\\n- When mentioning unrelated bugs/issues found\\n- Suggesting logical next steps user might want\\n- Structure longer answers with Markdown sections and lists, and put all code, commands, and config in fenced code blocks.\\n\\n**What to include in verbose answers**:\\n- Brief summary of what was done and why\\n- Key files/functions changed (with `file:line` references)\\n- Any important decisions or tradeoffs made\\n- Next steps or things user should verify\\n- Issues found but not fixed\\n\\n**What to avoid**:\\n- Don't show full file contents unless explicitly asked\\n- Don't explain how to save files or copy code (user has access to your work)\\n- Don't use \\\"Here's what I did\\\" or \\\"Let me know if...\\\" style preambles/postambles\\n- Keep tone direct and factual, like handing off work to a teammate\\n</final_answers>\\n\\n<env>\\nWorking directory: /tmp/crush-test/TestCoderAgent/openrouter-kimi-k2/sourcegraph_tool\\nIs directory a git repo: no\\nPlatform: linux\\nToday's date: 1/1/2025\\n\\n</env>\\n\\n\\n\\n\\n\",\"role\":\"system\",\"cache_control\":{\"type\":\"ephemeral\"}},{\"content\":\"<system_reminder>This is a reminder that your todo list is currently empty. DO NOT mention this to the user explicitly because they are already aware.\\nIf you are working on tasks that would benefit from a todo list please use the \\\"todos\\\" tool to create one.\\nIf not, please feel free to ignore. Again do not mention this message to the user.</system_reminder>\",\"role\":\"user\"},{\"content\":\"use sourcegraph to search for 'func main' in Go repositories\",\"role\":\"user\"},{\"tool_calls\":[{\"id\":\"functions.sourcegraph:0\",\"function\":{\"arguments\":\"{\\\"query\\\": \\\"func main lang:go\\\"}\",\"name\":\"sourcegraph\"},\"type\":\"function\",\"cache_control\":{\"type\":\"ephemeral\"}}],\"role\":\"assistant\"},{\"content\":\"# Sourcegraph Search Results\\n\\nFound 30 matches across 30 results\\n(Result limit reached, try a more specific query)\\n\\n## Result 1: github.com/Balun-courses/deep_go/lessons/functions/defer_with_function/main.go\\n\\nURL: /r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/defer_with_function/main.go\\n\\n```\\n8| }\\n9| \\n10| func handle(string) {\\n11| \\tfmt.Println(\\\"3\\\")\\n12| }\\n13| \\n14| func process() {\\n15| \\tdefer handle(get())\\n16| \\tfmt.Println(\\\"2\\\")\\n17| }\\n18| func main() {\\n19| func main() {\\n20| \\tprocess()\\n21| }\\n22| \\n```\\n\\n```\\n0| package main\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func get() string {\\n6| \\tfmt.Println(\\\"1\\\")\\n7| \\treturn \\\"\\\"\\n8| }\\n9| \\n10| func handle(string) {\\n```\\n\\n```\\n3| import \\\"fmt\\\"\\n4| \\n5| func get() string {\\n6| \\tfmt.Println(\\\"1\\\")\\n7| \\treturn \\\"\\\"\\n8| }\\n9| \\n10| func handle(string) {\\n11| \\tfmt.Println(\\\"3\\\")\\n12| }\\n13| func process() {\\n14| func process() {\\n15| \\tdefer handle(get())\\n16| \\tfmt.Println(\\\"2\\\")\\n17| }\\n18| \\n19| func main() {\\n20| \\tprocess()\\n21| }\\n22| \\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| func get() string {\\n5| func get() string {\\n6| \\tfmt.Println(\\\"1\\\")\\n7| \\treturn \\\"\\\"\\n8| }\\n9| \\n10| func handle(string) {\\n11| \\tfmt.Println(\\\"3\\\")\\n12| }\\n13| \\n14| func process() {\\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func get() string {\\n6| \\tfmt.Println(\\\"1\\\")\\n7| \\treturn \\\"\\\"\\n8| }\\n9| func handle(string) {\\n10| func handle(string) {\\n11| \\tfmt.Println(\\\"3\\\")\\n12| }\\n13| \\n14| func process() {\\n15| \\tdefer handle(get())\\n16| \\tfmt.Println(\\\"2\\\")\\n17| }\\n18| \\n19| func main() {\\n```\\n\\n## Result 2: github.com/Balun-courses/deep_go/lessons/functions/high_order_function/main.go\\n\\nURL: /r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/high_order_function/main.go\\n\\n```\\n3| import \\\"fmt\\\"\\n4| \\n5| func forEach(data []int, fn func(int) int) []int {\\n6| \\tnewData := make([]int, 0, len(data))\\n7| \\tfor _, value := range data {\\n8| \\t\\tnewData = append(newData, fn(value))\\n9| \\t}\\n10| \\n11| \\treturn newData\\n12| }\\n13| func main() {\\n14| func main() {\\n15| \\tvar data = []int{1, 2, 3, 4}\\n16| \\tvar newData = forEach(data, func(value int) int {\\n17| \\t\\treturn (value * value)\\n18| \\t})\\n19| \\n20| \\tfmt.Println(data)\\n21| \\tfmt.Println(newData)\\n22| }\\n23| \\n```\\n\\n```\\n5| func forEach(data []int, fn func(int) int) []int {\\n6| \\tnewData := make([]int, 0, len(data))\\n7| \\tfor _, value := range data {\\n8| \\t\\tnewData = append(newData, fn(value))\\n9| \\t}\\n10| \\n11| \\treturn newData\\n12| }\\n13| \\n14| func main() {\\n15| \\tvar newData = forEach(data, func(value int) int {\\n16| \\tvar newData = forEach(data, func(value int) int {\\n17| \\t\\treturn (value * value)\\n18| \\t})\\n19| \\n20| \\tfmt.Println(data)\\n21| \\tfmt.Println(newData)\\n22| }\\n23| \\n```\\n\\n```\\n0| package main\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func forEach(data []int, fn func(int) int) []int {\\n6| \\tnewData := make([]int, 0, len(data))\\n7| \\tfor _, value := range data {\\n8| \\t\\tnewData = append(newData, fn(value))\\n9| \\t}\\n10| \\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| func forEach(data []int, fn func(int) int) []int {\\n5| func forEach(data []int, fn func(int) int) []int {\\n6| \\tnewData := make([]int, 0, len(data))\\n7| \\tfor _, value := range data {\\n8| \\t\\tnewData = append(newData, fn(value))\\n9| \\t}\\n10| \\n11| \\treturn newData\\n12| }\\n13| \\n14| func main() {\\n```\\n\\n## Result 3: github.com/Balun-courses/deep_go/lessons/functions/composition/main.go\\n\\nURL: /r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/composition/main.go\\n\\n```\\n12| \\n13| func compose(fn ...func(int) int) func(int) int {\\n14| \\treturn func(value int) int {\\n15| \\t\\tfor _, v := range fn {\\n16| \\t\\t\\tvalue = v(value)\\n17| \\t\\t}\\n18| \\n19| \\t\\treturn value\\n20| \\t}\\n21| }\\n22| func main() {\\n23| func main() {\\n24| \\tfn := compose(sqr, neg, sqr)\\n25| \\tfmt.Println(fn(4))\\n26| }\\n27| \\n```\\n\\n```\\n0| package main\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func sqr(number int) int {\\n6| \\treturn number * number\\n7| }\\n8| \\n9| func neg(number int) int {\\n10| \\treturn -number\\n```\\n\\n```\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func sqr(number int) int {\\n6| \\treturn number * number\\n7| }\\n8| \\n9| func neg(number int) int {\\n10| \\treturn -number\\n11| }\\n12| func compose(fn ...func(int) int) func(int) int {\\n13| func compose(fn ...func(int) int) func(int) int {\\n14| \\treturn func(value int) int {\\n15| \\t\\tfor _, v := range fn {\\n16| \\t\\t\\tvalue = v(value)\\n17| \\t\\t}\\n18| \\n19| \\t\\treturn value\\n20| \\t}\\n21| }\\n22| \\n```\\n\\n```\\n3| import \\\"fmt\\\"\\n4| \\n5| func sqr(number int) int {\\n6| \\treturn number * number\\n7| }\\n8| \\n9| func neg(number int) int {\\n10| \\treturn -number\\n11| }\\n12| \\n13| \\treturn func(value int) int {\\n14| \\treturn func(value int) int {\\n15| \\t\\tfor _, v := range fn {\\n16| \\t\\t\\tvalue = v(value)\\n17| \\t\\t}\\n18| \\n19| \\t\\treturn value\\n20| \\t}\\n21| }\\n22| \\n23| func main() {\\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| func sqr(number int) int {\\n5| func sqr(number int) int {\\n6| \\treturn number * number\\n7| }\\n8| \\n9| func neg(number int) int {\\n10| \\treturn -number\\n11| }\\n12| \\n13| func compose(fn ...func(int) int) func(int) int {\\n14| \\treturn func(value int) int {\\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func sqr(number int) int {\\n6| \\treturn number * number\\n7| }\\n8| func neg(number int) int {\\n9| func neg(number int) int {\\n10| \\treturn -number\\n11| }\\n12| \\n13| func compose(fn ...func(int) int) func(int) int {\\n14| \\treturn func(value int) int {\\n15| \\t\\tfor _, v := range fn {\\n16| \\t\\t\\tvalue = v(value)\\n17| \\t\\t}\\n18| \\n```\\n\\n## Result 4: github.com/Balun-courses/deep_go/lessons/functions/defer_evaluation_moment/main.go\\n\\nURL: /r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/defer_evaluation_moment/main.go\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| func main() {\\n5| func main() {\\n6| \\tvar f func()\\n7| \\tdefer f()\\n8| \\n9| \\tf = func() {\\n10| \\t\\tfmt.Println(true)\\n11| \\t}\\n12| }\\n13| \\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| \\tvar f func()\\n6| \\tvar f func()\\n7| \\tdefer f()\\n8| \\n9| \\tf = func() {\\n10| \\t\\tfmt.Println(true)\\n11| \\t}\\n12| }\\n13| \\n```\\n\\n```\\n0| package main\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func main() {\\n6| \\tvar f func()\\n7| \\tdefer f()\\n8| \\n9| \\tf = func() {\\n10| \\t\\tfmt.Println(true)\\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func main() {\\n6| \\tvar f func()\\n7| \\tdefer f()\\n8| \\tf = func() {\\n9| \\tf = func() {\\n10| \\t\\tfmt.Println(true)\\n11| \\t}\\n12| }\\n13| \\n```\\n\\n## Result 5: github.com/Balun-courses/deep_go/lessons/contexts/after_done/main.go\\n\\nURL: /r/github.com/Balun-courses/deep_go/-/blob/lessons/contexts/after_done/main.go\\n\\n```\\n9| // context.AfterFunc\\n10| \\n11| func WithCtxAfterFunc(ctx context.Context, action func()) {\\n12| \\tif action != nil {\\n13| \\t\\tgo func() {\\n14| \\t\\t\\t<-ctx.Done()\\n15| \\t\\t\\taction()\\n16| \\t\\t}()\\n17| \\t}\\n18| }\\n19| func main() {\\n20| func main() {\\n21| \\tctx, cancel := context.WithCancel(context.Background())\\n22| \\tWithCtxAfterFunc(ctx, func() {\\n23| \\t\\tfmt.Println(\\\"after\\\")\\n24| \\t})\\n25| \\n26| \\tcancel()\\n27| \\n28| \\ttime.Sleep(100 * time.Millisecond)\\n29| }\\n```\\n\\n```\\n11| func WithCtxAfterFunc(ctx context.Context, action func()) {\\n12| \\tif action != nil {\\n13| \\t\\tgo func() {\\n14| \\t\\t\\t<-ctx.Done()\\n15| \\t\\t\\taction()\\n16| \\t\\t}()\\n17| \\t}\\n18| }\\n19| \\n20| func main() {\\n21| \\tWithCtxAfterFunc(ctx, func() {\\n22| \\tWithCtxAfterFunc(ctx, func() {\\n23| \\t\\tfmt.Println(\\\"after\\\")\\n24| \\t})\\n25| \\n26| \\tcancel()\\n27| \\n28| \\ttime.Sleep(100 * time.Millisecond)\\n29| }\\n30| \\n```\\n\\n```\\n0| package main\\n1| package main\\n2| \\n3| import (\\n4| \\t\\\"context\\\"\\n5| \\t\\\"fmt\\\"\\n6| \\t\\\"time\\\"\\n7| )\\n8| \\n9| // context.AfterFunc\\n10| \\n```\\n\\n```\\n1| package main\\n2| \\n3| import (\\n4| \\t\\\"context\\\"\\n5| \\t\\\"fmt\\\"\\n6| \\t\\\"time\\\"\\n7| )\\n8| // context.AfterFunc\\n9| // context.AfterFunc\\n10| \\n11| func WithCtxAfterFunc(ctx context.Context, action func()) {\\n12| \\tif action != nil {\\n13| \\t\\tgo func() {\\n14| \\t\\t\\t<-ctx.Done()\\n15| \\t\\t\\taction()\\n16| \\t\\t}()\\n17| \\t}\\n18| }\\n```\\n\\n```\\n1| package main\\n2| \\n3| import (\\n4| \\t\\\"context\\\"\\n5| \\t\\\"fmt\\\"\\n6| \\t\\\"time\\\"\\n7| )\\n8| \\n9| // context.AfterFunc\\n10| func WithCtxAfterFunc(ctx context.Context, action func()) {\\n11| func WithCtxAfterFunc(ctx context.Context, action func()) {\\n12| \\tif action != nil {\\n13| \\t\\tgo func() {\\n14| \\t\\t\\t<-ctx.Done()\\n15| \\t\\t\\taction()\\n16| \\t\\t}()\\n17| \\t}\\n18| }\\n19| \\n20| func main() {\\n```\\n\\n\",\"tool_call_id\":\"functions.sourcegraph:0\",\"role\":\"tool\"}],\"model\":\"moonshotai/kimi-k2-0905\",\"max_tokens\":10000,\"stream_options\":{\"include_usage\":true},\"tool_choice\":\"auto\",\"tools\":[{\"function\":{\"name\":\"bash\",\"strict\":false,\"description\":\"Executes bash commands with automatic background conversion for long-running tasks.\\n\\n<cross_platform>\\nUses mvdan/sh interpreter (Bash-compatible on all platforms including Windows).\\nUse forward slashes for paths: \\\"ls C:/foo/bar\\\" not \\\"ls C:\\\\foo\\\\bar\\\".\\nCommon shell builtins and core utils available on Windows.\\n</cross_platform>\\n\\n<execution_steps>\\n1. Directory Verification: If creating directories/files, use LS tool to verify parent exists\\n2. Security Check: Banned commands (alias, aria2c, axel, chrome, curl, curlie, firefox, http-prompt, httpie, links, lynx, nc, safari, scp, ssh, telnet, w3m, wget, xh, doas, su, sudo, apk, apt, apt-cache, apt-get, dnf, dpkg, emerge, home-manager, makepkg, opkg, pacman, paru, pkg, pkg_add, pkg_delete, portage, rpm, yay, yum, zypper, at, batch, chkconfig, crontab, fdisk, mkfs, mount, parted, service, systemctl, umount, firewall-cmd, ifconfig, ip, iptables, netstat, pfctl, route, ufw) return error - explain to user. Safe read-only commands execute without prompts\\n3. Command Execution: Execute with proper quoting, capture output\\n4. Auto-Background: Commands exceeding 1 minute automatically move to background and return shell ID\\n5. Output Processing: Truncate if exceeds 30000 characters\\n6. Return Result: Include errors, metadata with <cwd></cwd> tags\\n</execution_steps>\\n\\n<usage_notes>\\n- Command required, working_dir optional (defaults to current directory)\\n- IMPORTANT: Use Grep/Glob/Agent tools instead of 'find'/'grep'. Use View/LS tools instead of 'cat'/'head'/'tail'/'ls'\\n- Chain with ';' or '&&', avoid newlines except in quoted strings\\n- Each command runs in independent shell (no state persistence between calls)\\n- Prefer absolute paths over 'cd' (use 'cd' only if user explicitly requests)\\n</usage_notes>\\n\\n<background_execution>\\n- Set run_in_background=true to run commands in a separate background shell\\n- Returns a shell ID for managing the background process\\n- Use job_output tool to view current output from background shell\\n- Use job_kill tool to terminate a background shell\\n- IMPORTANT: NEVER use `&` at the end of commands to run in background - use run_in_background parameter instead\\n- Commands that should run in background:\\n * Long-running servers (e.g., `npm start`, `python -m http.server`, `node server.js`)\\n * Watch/monitoring tasks (e.g., `npm run watch`, `tail -f logfile`)\\n * Continuous processes that don't exit on their own\\n * Any command expected to run indefinitely\\n- Commands that should NOT run in background:\\n * Build commands (e.g., `npm run build`, `go build`)\\n * Test suites (e.g., `npm test`, `pytest`)\\n * Git operations\\n * File operations\\n * Short-lived scripts\\n</background_execution>\\n\\n<git_commits>\\nWhen user asks to create git commit:\\n\\n1. Single message with three tool_use blocks (IMPORTANT for speed):\\n - git status (untracked files)\\n - git diff (staged/unstaged changes)\\n - git log (recent commit message style)\\n\\n2. Add relevant untracked files to staging. Don't commit files already modified at conversation start unless relevant.\\n\\n3. Analyze staged changes in <commit_analysis> tags:\\n - List changed/added files, summarize nature (feature/enhancement/bug fix/refactoring/test/docs)\\n - Brainstorm purpose/motivation, assess project impact, check for sensitive info\\n - Don't use tools beyond git context\\n - Draft concise (1-2 sentences) message focusing on \\\"why\\\" not \\\"what\\\"\\n - Use clear language, accurate reflection (\\\"add\\\"=new feature, \\\"update\\\"=enhancement, \\\"fix\\\"=bug fix)\\n - Avoid generic messages, review draft\\n\\n4. Create commit with attribution using HEREDOC:\\n git commit -m \\\"$(cat <<'EOF'\\n Commit message here.\\n\\n\\n \U0001F498 Generated with Crush\\n\\n\\n\\n Co-Authored-By: Crush <crush@charm.land>\\n\\n\\n EOF\\n )\\\"\\n\\n5. If pre-commit hook fails, retry ONCE. If fails again, hook preventing commit. If succeeds but files modified, MUST amend.\\n\\n6. Run git status to verify.\\n\\nNotes: Use \\\"git commit -am\\\" when possible, don't stage unrelated files, NEVER update config, don't push, no -i flags, no empty commits, return empty response.\\n</git_commits>\\n\\n<pull_requests>\\nUse gh command for ALL GitHub tasks. When user asks to create PR:\\n\\n1. Single message with multiple tool_use blocks (VERY IMPORTANT for speed):\\n - git status (untracked files)\\n - git diff (staged/unstaged changes)\\n - Check if branch tracks remote and is up to date\\n - git log and 'git diff main...HEAD' (full commit history from main divergence)\\n\\n2. Create new branch if needed\\n3. Commit changes if needed\\n4. Push to remote with -u flag if needed\\n\\n5. Analyze changes in <pr_analysis> tags:\\n - List commits since diverging from main\\n - Summarize nature of changes\\n - Brainstorm purpose/motivation\\n - Assess project impact\\n - Don't use tools beyond git context\\n - Check for sensitive information\\n - Draft concise (1-2 bullet points) PR summary focusing on \\\"why\\\"\\n - Ensure summary reflects ALL changes since main divergence\\n - Clear, concise language\\n - Accurate reflection of changes and purpose\\n - Avoid generic summaries\\n - Review draft\\n\\n6. Create PR with gh pr create using HEREDOC:\\n gh pr create --title \\\"title\\\" --body \\\"$(cat <<'EOF'\\n\\n ## Summary\\n\\n <1-3 bullet points>\\n\\n ## Test plan\\n\\n [Checklist of TODOs...]\\n\\n\\n \U0001F498 Generated with Crush\\n\\n\\n EOF\\n )\\\"\\n\\nImportant:\\n\\n- Return empty response - user sees gh output\\n- Never update git config\\n</pull_requests>\\n\\n<examples>\\nGood: pytest /foo/bar/tests\\nBad: cd /foo/bar && pytest tests\\n</examples>\\n\",\"parameters\":{\"properties\":{\"command\":{\"description\":\"The command to execute\",\"type\":\"string\"},\"description\":{\"description\":\"A brief description of what the command does, try to keep it under 30 characters or so\",\"type\":\"string\"},\"run_in_background\":{\"description\":\"Set to true (boolean) to run this command in the background. Use job_output to read the output later.\",\"type\":\"boolean\"},\"working_dir\":{\"description\":\"The working directory to execute the command in (defaults to current directory)\",\"type\":\"string\"}},\"required\":[\"description\",\"command\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"download\",\"strict\":false,\"description\":\"Downloads binary data from URL and saves to local file.\\n\\n<usage>\\n- Provide URL to download from\\n- Specify local file path where content should be saved\\n- Optional timeout for request\\n</usage>\\n\\n<features>\\n- Downloads any file type (binary or text)\\n- Auto-creates parent directories if missing\\n- Handles large files efficiently with streaming\\n- Sets reasonable timeouts to prevent hanging\\n- Validates input parameters before requests\\n</features>\\n\\n<limitations>\\n- Max file size: 100MB\\n- Only supports HTTP and HTTPS protocols\\n- Cannot handle authentication or cookies\\n- Some websites may block automated requests\\n- Will overwrite existing files without warning\\n</limitations>\\n\\n<tips>\\n- Use absolute paths or paths relative to working directory\\n- Set appropriate timeouts for large files or slow connections\\n</tips>\\n\",\"parameters\":{\"properties\":{\"file_path\":{\"description\":\"The local file path where the downloaded content should be saved\",\"type\":\"string\"},\"timeout\":{\"description\":\"Optional timeout in seconds (max 600)\",\"type\":\"integer\"},\"url\":{\"description\":\"The URL to download from\",\"type\":\"string\"}},\"required\":[\"url\",\"file_path\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"edit\",\"strict\":false,\"description\":\"Edits files by replacing text, creating new files, or deleting content. For moving/renaming use Bash 'mv'. For large edits use Write tool.\\n\\n<prerequisites>\\n1. Use View tool to understand file contents and context\\n2. For new files: Use LS tool to verify parent directory exists\\n3. **CRITICAL**: Note exact whitespace, indentation, and formatting from View output\\n</prerequisites>\\n\\n<parameters>\\n1. file_path: Absolute path to file (required)\\n2. old_string: Text to replace (must match exactly including whitespace/indentation)\\n3. new_string: Replacement text\\n4. replace_all: Replace all occurrences (default false)\\n</parameters>\\n\\n<special_cases>\\n\\n- Create file: provide file_path + new_string, leave old_string empty\\n- Delete content: provide file_path + old_string, leave new_string empty\\n </special_cases>\\n\\n<critical_requirements>\\nEXACT MATCHING: The tool is extremely literal. Text must match **EXACTLY**\\n\\n- Every space and tab character\\n- Every blank line\\n- Every newline character\\n- Indentation level (count the spaces/tabs)\\n- Comment spacing (`// comment` vs `//comment`)\\n- Brace positioning (`func() {` vs `func(){`)\\n\\nCommon failures:\\n\\n```\\nExpected: \\\" func foo() {\\\" (4 spaces)\\nProvided: \\\" func foo() {\\\" (2 spaces) ❌ FAILS\\n\\nExpected: \\\"}\\\\n\\\\nfunc bar() {\\\" (2 newlines)\\nProvided: \\\"}\\\\nfunc bar() {\\\" (1 newline) ❌ FAILS\\n\\nExpected: \\\"// Comment\\\" (space after //)\\nProvided: \\\"//Comment\\\" (no space) ❌ FAILS\\n```\\n\\nUNIQUENESS (when replace_all=false): old_string MUST uniquely identify target instance\\n\\n- Include 3-5 lines context BEFORE and AFTER change point\\n- Include exact whitespace, indentation, surrounding code\\n- If text appears multiple times, add more context to make it unique\\n\\nSINGLE INSTANCE: Tool changes ONE instance when replace_all=false\\n\\n- For multiple instances: set replace_all=true OR make separate calls with unique context\\n- Plan calls carefully to avoid conflicts\\n\\nVERIFICATION BEFORE USING: Before every edit\\n\\n1. View the file and locate exact target location\\n2. Check how many instances of target text exist\\n3. Copy the EXACT text including all whitespace\\n4. Verify you have enough context for unique identification\\n5. Double-check indentation matches (count spaces/tabs)\\n6. Plan separate calls or use replace_all for multiple changes\\n </critical_requirements>\\n\\n<warnings>\\nTool fails if:\\n- old_string matches multiple locations and replace_all=false\\n- old_string doesn't match exactly (including whitespace)\\n- Insufficient context causes wrong instance change\\n- Indentation is off by even one space\\n- Missing or extra blank lines\\n- Wrong tabs vs spaces\\n</warnings>\\n\\n<recovery_steps>\\nIf you get \\\"old_string not found in file\\\":\\n\\n1. **View the file again** at the specific location\\n2. **Copy more context** - include entire function if needed\\n3. **Check whitespace**:\\n - Count indentation spaces/tabs\\n - Look for blank lines\\n - Check for trailing spaces\\n4. **Verify character-by-character** that your old_string matches\\n5. **Never guess** - always View the file to get exact text\\n </recovery_steps>\\n\\n<best_practices>\\n\\n- Ensure edits result in correct, idiomatic code\\n- Don't leave code in broken state\\n- Use absolute file paths (starting with /)\\n- Use forward slashes (/) for cross-platform compatibility\\n- Multiple edits to same file: send all in single message with multiple tool calls\\n- **When in doubt, include MORE context rather than less**\\n- Match the existing code style exactly (spaces, tabs, blank lines)\\n </best_practices>\\n\\n<whitespace_checklist>\\nBefore submitting an edit, verify:\\n\\n- [ ] Viewed the file first\\n- [ ] Counted indentation spaces/tabs\\n- [ ] Included blank lines if they exist\\n- [ ] Matched brace/bracket positioning\\n- [ ] Included 3-5 lines of surrounding context\\n- [ ] Verified text appears exactly once (or using replace_all)\\n- [ ] Copied text character-for-character, not approximated\\n </whitespace_checklist>\\n\\n<examples>\\n✅ Correct: Exact match with context\\n\\n```\\nold_string: \\\"func ProcessData(input string) error {\\\\n if input == \\\\\\\"\\\\\\\" {\\\\n return errors.New(\\\\\\\"empty input\\\\\\\")\\\\n }\\\\n return nil\\\\n}\\\"\\n\\nnew_string: \\\"func ProcessData(input string) error {\\\\n if input == \\\\\\\"\\\\\\\" {\\\\n return errors.New(\\\\\\\"empty input\\\\\\\")\\\\n }\\\\n // New validation\\\\n if len(input) > 1000 {\\\\n return errors.New(\\\\\\\"input too long\\\\\\\")\\\\n }\\\\n return nil\\\\n}\\\"\\n```\\n\\n❌ Incorrect: Not enough context\\n\\n```\\nold_string: \\\"return nil\\\" // Appears many times!\\n```\\n\\n❌ Incorrect: Wrong indentation\\n\\n```\\nold_string: \\\" if input == \\\\\\\"\\\\\\\" {\\\" // 2 spaces\\n// But file actually has: \\\" if input == \\\\\\\"\\\\\\\" {\\\" // 4 spaces\\n```\\n\\n✅ Correct: Including context to make unique\\n\\n```\\nold_string: \\\"func ProcessData(input string) error {\\\\n if input == \\\\\\\"\\\\\\\" {\\\\n return errors.New(\\\\\\\"empty input\\\\\\\")\\\\n }\\\\n return nil\\\"\\n```\\n\\n</examples>\\n\\n<windows_notes>\\n\\n- Forward slashes work throughout (C:/path/file)\\n- File permissions handled automatically\\n- Line endings converted automatically (\\\\n ↔ \\\\r\\\\n)\\n </windows_notes>\\n\",\"parameters\":{\"properties\":{\"file_path\":{\"description\":\"The absolute path to the file to modify\",\"type\":\"string\"},\"new_string\":{\"description\":\"The text to replace it with\",\"type\":\"string\"},\"old_string\":{\"description\":\"The text to replace\",\"type\":\"string\"},\"replace_all\":{\"description\":\"Replace all occurrences of old_string (default false)\",\"type\":\"boolean\"}},\"required\":[\"file_path\",\"old_string\",\"new_string\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"multiedit\",\"strict\":false,\"description\":\"Makes multiple edits to a single file in one operation. Built on Edit tool for efficient multiple find-and-replace operations. Prefer over Edit tool for multiple edits to same file.\\n\\n<prerequisites>\\n1. Use View tool to understand file contents and context\\n2. Verify directory path is correct\\n3. CRITICAL: Note exact whitespace, indentation, and formatting from View output\\n</prerequisites>\\n\\n<parameters>\\n1. file_path: Absolute path to file (required)\\n2. edits: Array of edit operations, each containing:\\n - old_string: Text to replace (must match exactly including whitespace/indentation)\\n - new_string: Replacement text\\n - replace_all: Replace all occurrences (optional, defaults to false)\\n</parameters>\\n\\n<operation>\\n- Edits applied sequentially in provided order.\\n- Each edit operates on result of previous edit.\\n- PARTIAL SUCCESS: If some edits fail, successful edits are still applied. Failed edits are returned in the response.\\n- File is modified if at least one edit succeeds.\\n- Ideal for several changes to different parts of same file.\\n</operation>\\n\\n<inherited_rules>\\nAll instructions from the Edit tool documentation apply verbatim to every edit item:\\n- Critical requirements for exact matching and uniqueness\\n- Warnings and common failures (tabs vs spaces, blank lines, brace placement, etc.)\\n- Verification steps before using, recovery steps, best practices, and whitespace checklist\\nUse the same level of precision as Edit. Multiedit often fails due to formatting mismatches—double-check whitespace for every edit.\\n</inherited_rules>\\n\\n<critical_requirements>\\n1. Apply Edit tool rules to EACH edit (see edit.md).\\n2. Edits are applied in order; successful edits are kept even if later edits fail.\\n3. Plan sequence carefully: earlier edits change the file content that later edits must match.\\n4. Ensure each old_string is unique at its application time (after prior edits).\\n5. Check the response for failed edits and retry them if needed.\\n</critical_requirements>\\n\\n<verification_before_using>\\n1. View the file and copy exact text (including whitespace) for each target.\\n2. Check how many instances each old_string has BEFORE the sequence starts.\\n3. Dry-run mentally: after applying edit #N, will edit #N+1 still match? Adjust old_string/new_string accordingly.\\n4. Prefer fewer, larger context blocks over many tiny fragments that are easy to misalign.\\n5. If edits are independent, consider separate multiedit batches per logical region.\\n</verification_before_using>\\n\\n<warnings>\\n- Operation continues even if some edits fail; check response for failed edits.\\n- Earlier edits can invalidate later matches (added/removed spaces, lines, or reordered text).\\n- Mixed tabs/spaces, trailing spaces, or missing blank lines commonly cause failures.\\n- replace_all may affect unintended regions—use carefully or provide more context.\\n</warnings>\\n\\n<recovery_steps>\\nIf some edits fail:\\n1. Check the response metadata for the list of failed edits with their error messages.\\n2. View the file again to see the current state after successful edits.\\n3. Adjust the failed edits based on the new file content.\\n4. Retry the failed edits with corrected old_string values.\\n5. Consider breaking complex batches into smaller, independent operations.\\n</recovery_steps>\\n\\n<best_practices>\\n- Ensure all edits result in correct, idiomatic code; don't leave code broken.\\n- Use absolute file paths (starting with /).\\n- Use replace_all only when you're certain; otherwise provide unique context.\\n- Match existing style exactly (spaces, tabs, blank lines).\\n- Review failed edits in the response and retry with corrections.\\n</best_practices>\\n\\n<whitespace_checklist>\\nFor EACH edit, verify:\\n- [ ] Viewed the file first\\n- [ ] Counted indentation spaces/tabs\\n- [ ] Included blank lines if present\\n- [ ] Matched brace/bracket positioning\\n- [ ] Included 3–5 lines of surrounding context\\n- [ ] Verified text appears exactly once (or using replace_all deliberately)\\n- [ ] Copied text character-for-character, not approximated\\n</whitespace_checklist>\\n\\n<examples>\\n✅ Correct: Sequential edits where the second match accounts for the first change\\n\\n```\\nedits: [\\n {\\n old_string: \\\"func A() {\\\\n doOld()\\\\n}\\\",\\n new_string: \\\"func A() {\\\\n doNew()\\\\n}\\\",\\n },\\n {\\n // Uses context that still exists AFTER the first replacement\\n old_string: \\\"func B() {\\\\n callA()\\\\n}\\\",\\n new_string: \\\"func B() {\\\\n callA()\\\\n logChange()\\\\n}\\\",\\n },\\n]\\n```\\n\\n❌ Incorrect: Second old_string no longer matches due to whitespace change introduced by the first edit\\n\\n```\\nedits: [\\n {\\n old_string: \\\"func A() {\\\\n doOld()\\\\n}\\\",\\n new_string: \\\"func A() {\\\\n\\\\n doNew()\\\\n}\\\", // Added extra blank line\\n },\\n {\\n old_string: \\\"func A() {\\\\n doNew()\\\\n}\\\", // Missing the new blank line, will FAIL\\n new_string: \\\"func A() {\\\\n doNew()\\\\n logChange()\\\\n}\\\",\\n },\\n]\\n```\\n\\n✅ Correct: Handling partial success\\n\\n```\\n// If edit 2 fails, edit 1 is still applied\\n// Response will indicate:\\n// - edits_applied: 1\\n// - edits_failed: [{index: 2, error: \\\"...\\\", edit: {...}}]\\n// You can then retry edit 2 with corrected context\\n```\\n</examples>\\n\",\"parameters\":{\"properties\":{\"edits\":{\"description\":\"Array of edit operations to perform sequentially on the file\",\"items\":{\"properties\":{\"new_string\":{\"description\":\"The text to replace it with\",\"type\":\"string\"},\"old_string\":{\"description\":\"The text to replace\",\"type\":\"string\"},\"replace_all\":{\"description\":\"Replace all occurrences of old_string (default false).\",\"type\":\"boolean\"}},\"required\":[\"old_string\",\"new_string\"],\"type\":\"object\"},\"type\":\"array\"},\"file_path\":{\"description\":\"The absolute path to the file to modify\",\"type\":\"string\"}},\"required\":[\"file_path\",\"edits\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"fetch\",\"strict\":false,\"description\":\"Fetches raw content from URL and returns it in specified format without any AI processing.\\n\\n<when_to_use>\\nUse this tool when you need:\\n- Raw, unprocessed content from a URL\\n- Direct access to API responses or JSON data\\n- HTML/text/markdown content without interpretation\\n- Simple, fast content retrieval without analysis\\n- To save tokens by avoiding AI processing\\n\\nDO NOT use this tool when you need to:\\n- Extract specific information from a webpage (use agentic_fetch instead)\\n- Answer questions about web content (use agentic_fetch instead)\\n- Analyze or summarize web pages (use agentic_fetch instead)\\n</when_to_use>\\n\\n<usage>\\n- Provide URL to fetch content from\\n- Specify desired output format (text, markdown, or html)\\n- Optional timeout for request\\n</usage>\\n\\n<features>\\n- Supports three output formats: text, markdown, html\\n- Auto-handles HTTP redirects\\n- Fast and lightweight - no AI processing\\n- Sets reasonable timeouts to prevent hanging\\n- Validates input parameters before requests\\n</features>\\n\\n<limitations>\\n- Max response size: 5MB\\n- Only supports HTTP and HTTPS protocols\\n- Cannot handle authentication or cookies\\n- Some websites may block automated requests\\n- Returns raw content only - no analysis or extraction\\n</limitations>\\n\\n<tips>\\n- Use text format for plain text content or simple API responses\\n- Use markdown format for content that should be rendered with formatting\\n- Use html format when you need raw HTML structure\\n- Set appropriate timeouts for potentially slow websites\\n- If the user asks to analyze or extract from a page, use agentic_fetch instead\\n</tips>\\n\",\"parameters\":{\"properties\":{\"format\":{\"description\":\"The format to return the content in (text, markdown, or html)\",\"type\":\"string\"},\"timeout\":{\"description\":\"Optional timeout in seconds (max 120)\",\"type\":\"integer\"},\"url\":{\"description\":\"The URL to fetch content from\",\"type\":\"string\"}},\"required\":[\"url\",\"format\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"glob\",\"strict\":false,\"description\":\"Fast file pattern matching tool that finds files by name/pattern, returning paths sorted by modification time (newest first).\\n\\n<usage>\\n- Provide glob pattern to match against file paths\\n- Optional starting directory (defaults to current working directory)\\n- Results sorted with most recently modified files first\\n</usage>\\n\\n<pattern_syntax>\\n- '\\\\*' matches any sequence of non-separator characters\\n- '\\\\*\\\\*' matches any sequence including separators\\n- '?' matches any single non-separator character\\n- '[...]' matches any character in brackets\\n- '[!...]' matches any character not in brackets\\n</pattern_syntax>\\n\\n<examples>\\n- '*.js' - JavaScript files in current directory\\n- '**/*.js' - JavaScript files in any subdirectory\\n- 'src/**/*.{ts,tsx}' - TypeScript files in src directory\\n- '*.{html,css,js}' - HTML, CSS, and JS files\\n</examples>\\n\\n<limitations>\\n- Results limited to 100 files (newest first)\\n- Does not search file contents (use Grep for that)\\n- Hidden files (starting with '.') skipped\\n</limitations>\\n\\n<cross_platform>\\n- Path separators handled automatically (/ and \\\\ work)\\n- Uses ripgrep (rg) if available, otherwise Go implementation\\n- Patterns should use forward slashes (/) for compatibility\\n</cross_platform>\\n\\n<tips>\\n- Combine with Grep: find files with Glob, search contents with Grep\\n- For iterative exploration requiring multiple searches, consider Agent tool\\n- Check if results truncated and refine pattern if needed\\n</tips>\\n\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The directory to search in. Defaults to the current working directory.\",\"type\":\"string\"},\"pattern\":{\"description\":\"The glob pattern to match files against\",\"type\":\"string\"}},\"required\":[\"pattern\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"grep\",\"strict\":false,\"description\":\"Fast content search tool that finds files containing specific text/patterns, returning matching paths sorted by modification time (newest first).\\n\\n<usage>\\n- Provide regex pattern to search within file contents\\n- Set literal_text=true for exact text with special characters (recommended for non-regex users)\\n- Optional starting directory (defaults to current working directory)\\n- Optional include pattern to filter which files to search\\n- Results sorted with most recently modified files first\\n</usage>\\n\\n<regex_syntax>\\nWhen literal_text=false (supports standard regex):\\n\\n- 'function' searches for literal text \\\"function\\\"\\n- 'log\\\\..\\\\*Error' finds text starting with \\\"log.\\\" and ending with \\\"Error\\\"\\n- 'import\\\\s+.\\\\*\\\\s+from' finds import statements in JavaScript/TypeScript\\n</regex_syntax>\\n\\n<include_patterns>\\n- '\\\\*.js' - Only search JavaScript files\\n- '\\\\*.{ts,tsx}' - Only search TypeScript files\\n- '\\\\*.go' - Only search Go files\\n</include_patterns>\\n\\n<limitations>\\n- Results limited to 100 files (newest first)\\n- Performance depends on number of files searched\\n- Very large binary files may be skipped\\n- Hidden files (starting with '.') skipped\\n</limitations>\\n\\n<ignore_support>\\n- Respects .gitignore patterns to skip ignored files/directories\\n- Respects .crushignore patterns for additional ignore rules\\n- Both ignore files auto-detected in search root directory\\n</ignore_support>\\n\\n<cross_platform>\\n- Uses ripgrep (rg) if available for better performance\\n- Falls back to Go implementation if ripgrep unavailable\\n- File paths normalized automatically for compatibility\\n</cross_platform>\\n\\n<tips>\\n- For faster searches: use Glob to find relevant files first, then Grep\\n- For iterative exploration requiring multiple searches, consider Agent tool\\n- Check if results truncated and refine search pattern if needed\\n- Use literal_text=true for exact text with special characters (dots, parentheses, etc.)\\n</tips>\\n\",\"parameters\":{\"properties\":{\"include\":{\"description\":\"File pattern to include in the search (e.g. \\\"*.js\\\", \\\"*.{ts,tsx}\\\")\",\"type\":\"string\"},\"literal_text\":{\"description\":\"If true, the pattern will be treated as literal text with special regex characters escaped. Default is false.\",\"type\":\"boolean\"},\"path\":{\"description\":\"The directory to search in. Defaults to the current working directory.\",\"type\":\"string\"},\"pattern\":{\"description\":\"The regex pattern to search for in file contents\",\"type\":\"string\"}},\"required\":[\"pattern\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"ls\",\"strict\":false,\"description\":\"Shows files and subdirectories in tree structure for exploring project organization.\\n\\n<usage>\\n- Provide path to list (defaults to current working directory)\\n- Optional glob patterns to ignore\\n- Results displayed in tree structure\\n</usage>\\n\\n<features>\\n- Hierarchical view of files and directories\\n- Auto-skips hidden files/directories (starting with '.')\\n- Skips common system directories like __pycache__\\n- Can filter files matching specific patterns\\n</features>\\n\\n<limitations>\\n- Results limited to 1000 files\\n- Large directories truncated\\n- No file sizes or permissions shown\\n- Cannot recursively list all directories in large projects\\n</limitations>\\n\\n<cross_platform>\\n- Hidden file detection uses Unix convention (files starting with '.')\\n- Windows hidden files (with hidden attribute) not auto-skipped\\n- Common Windows directories (System32, Program Files) not in default ignore\\n- Path separators handled automatically (/ and \\\\ work)\\n</cross_platform>\\n\\n<tips>\\n- Use Glob for finding files by name patterns instead of browsing\\n- Use Grep for searching file contents\\n- Combine with other tools for effective exploration\\n</tips>\\n\",\"parameters\":{\"properties\":{\"depth\":{\"description\":\"The maximum depth to traverse\",\"type\":\"integer\"},\"ignore\":{\"description\":\"List of glob patterns to ignore\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"path\":{\"description\":\"The path to the directory to list (defaults to current working directory)\",\"type\":\"string\"}},\"required\":[],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"sourcegraph\",\"strict\":false,\"description\":\"Search code across public repositories using Sourcegraph's GraphQL API.\\n\\n<usage>\\n- Provide search query using Sourcegraph syntax\\n- Optional result count (default: 10, max: 20)\\n- Optional timeout for request\\n</usage>\\n\\n<basic_syntax>\\n- \\\"fmt.Println\\\" - exact matches\\n- \\\"file:.go fmt.Println\\\" - limit to Go files\\n- \\\"repo:^github\\\\.com/golang/go$ fmt.Println\\\" - specific repos\\n- \\\"lang:go fmt.Println\\\" - limit to Go code\\n- \\\"fmt.Println AND log.Fatal\\\" - combined terms\\n- \\\"fmt\\\\.(Print|Printf|Println)\\\" - regex patterns\\n- \\\"\\\\\\\"exact phrase\\\\\\\"\\\" - exact phrase matching\\n- \\\"-file:test\\\" or \\\"-repo:forks\\\" - exclude matches\\n</basic_syntax>\\n\\n<key_filters>\\nRepository: repo:name, repo:^exact$, repo:org/repo@branch, -repo:exclude, fork:yes, archived:yes, visibility:public\\nFile: file:\\\\.js$, file:internal/, -file:test, file:has.content(text)\\nContent: content:\\\"exact\\\", -content:\\\"unwanted\\\", case:yes\\nType: type:symbol, type:file, type:path, type:diff, type:commit\\nTime: after:\\\"1 month ago\\\", before:\\\"2023-01-01\\\", author:name, message:\\\"fix\\\"\\nResult: select:repo, select:file, select:content, count:100, timeout:30s\\n</key_filters>\\n\\n<examples>\\n- \\\"file:.go context.WithTimeout\\\" - Go code using context.WithTimeout\\n- \\\"lang:typescript useState type:symbol\\\" - TypeScript React useState hooks\\n- \\\"repo:^github\\\\.com/kubernetes/kubernetes$ pod list type:file\\\" - Kubernetes pod files\\n- \\\"file:Dockerfile (alpine OR ubuntu) -content:alpine:latest\\\" - Dockerfiles with base images\\n</examples>\\n\\n<boolean_operators>\\n- \\\"term1 AND term2\\\" - both terms\\n- \\\"term1 OR term2\\\" - either term\\n- \\\"term1 NOT term2\\\" - term1 but not term2\\n- \\\"term1 and (term2 or term3)\\\" - grouping with parentheses\\n</boolean_operators>\\n\\n<limitations>\\n- Only searches public repositories\\n- Rate limits may apply\\n- Complex queries take longer\\n- Max 20 results per query\\n</limitations>\\n\\n<tips>\\n- Use specific file extensions to narrow results\\n- Add repo: filters for targeted searches\\n- Use type:symbol for function/method definitions\\n- Use type:file to find relevant files\\n</tips>\\n\",\"parameters\":{\"properties\":{\"context_window\":{\"description\":\"The context around the match to return (default: 10 lines)\",\"type\":\"integer\"},\"count\":{\"description\":\"Optional number of results to return (default: 10, max: 20)\",\"type\":\"integer\"},\"query\":{\"description\":\"The Sourcegraph search query\",\"type\":\"string\"},\"timeout\":{\"description\":\"Optional timeout in seconds (max 120)\",\"type\":\"integer\"}},\"required\":[\"query\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"view\",\"strict\":false,\"description\":\"Reads and displays file contents with line numbers for examining code, logs, or text data.\\n\\n<usage>\\n- Provide file path to read\\n- Optional offset: start reading from specific line (0-based)\\n- Optional limit: control lines read (default 2000)\\n- Don't use for directories (use LS tool instead)\\n- Supports image files (PNG, JPEG, GIF, BMP, SVG, WebP)\\n</usage>\\n\\n<features>\\n- Displays contents with line numbers\\n- Can read from any file position using offset\\n- Handles large files by limiting lines read\\n- Auto-truncates very long lines for display\\n- Suggests similar filenames when file not found\\n- Renders image files directly in terminal\\n</features>\\n\\n<limitations>\\n- Max file size: 5MB\\n- Default limit: 2000 lines\\n- Lines >2000 chars truncated\\n- Binary files (except images) cannot be displayed\\n</limitations>\\n\\n<cross_platform>\\n- Handles Windows (CRLF) and Unix (LF) line endings\\n- Works with forward slashes (/) and backslashes (\\\\)\\n- Auto-detects text encoding for common formats\\n</cross_platform>\\n\\n<tips>\\n- Use with Glob to find files first\\n- For code exploration: Grep to find relevant files, then View to examine\\n- For large files: use offset parameter for specific sections\\n- View tool automatically detects and renders image files\\n</tips>\\n\",\"parameters\":{\"properties\":{\"file_path\":{\"description\":\"The path to the file to read\",\"type\":\"string\"},\"limit\":{\"description\":\"The number of lines to read (defaults to 2000)\",\"type\":\"integer\"},\"offset\":{\"description\":\"The line number to start reading from (0-based)\",\"type\":\"integer\"}},\"required\":[\"file_path\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"write\",\"strict\":false,\"description\":\"Creates or updates files in filesystem for saving/modifying text content.\\n\\n<usage>\\n- Provide file path to write\\n- Include content to write to file\\n- Tool creates necessary parent directories automatically\\n</usage>\\n\\n<features>\\n- Creates new files or overwrites existing ones\\n- Auto-creates parent directories if missing\\n- Checks if file modified since last read for safety\\n- Avoids unnecessary writes when content unchanged\\n</features>\\n\\n<limitations>\\n- Read file before writing to avoid conflicts\\n- Cannot append (rewrites entire file)\\n</limitations>\\n\\n<cross_platform>\\n- Use forward slashes (/) for compatibility\\n</cross_platform>\\n\\n<tips>\\n- Use View tool first to examine existing files before modifying\\n- Use LS tool to verify location when creating new files\\n- Combine with Glob/Grep to find and modify multiple files\\n- Include descriptive comments when changing existing code\\n</tips>\\n\",\"parameters\":{\"properties\":{\"content\":{\"description\":\"The content to write to the file\",\"type\":\"string\"},\"file_path\":{\"description\":\"The path to the file to write\",\"type\":\"string\"}},\"required\":[\"file_path\",\"content\"],\"type\":\"object\"}},\"type\":\"function\"}],\"usage\":{\"include\":true},\"stream\":true}"
134 headers:
135 Accept:
136 - application/json
137 Content-Type:
138 - application/json
139 User-Agent:
140 - OpenAI/Go 2.7.1
141 url: https://openrouter.ai/api/v1/chat/completions
142 method: POST
143 response:
144 proto: HTTP/2.0
145 proto_major: 2
146 proto_minor: 0
147 content_length: -1
148 body: |+
149 data: {"id":"gen-1773004301-OBBlcdTOwgZugkI2ltOq","object":"chat.completion.chunk","created":1773004301,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":null,"role":"assistant","tool_calls":[{"index":0,"id":"functions.sourcegraph:1","type":"function","function":{"name":"sourcegraph","arguments":""}}]},"finish_reason":null,"native_finish_reason":null}]}
150
151 data: {"id":"gen-1773004301-OBBlcdTOwgZugkI2ltOq","object":"chat.completion.chunk","created":1773004301,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":null,"role":"assistant","tool_calls":[{"index":0,"function":{"arguments":"{\"query\": \": \\\"func main lang:go type:file\\\"}\"}"}}]},"finish_reason":null,"native_finish_reason":null}]}
152
153 data: {"id":"gen-1773004301-OBBlcdTOwgZugkI2ltOq","object":"chat.completion.chunk","created":1773004301,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"","role":"assistant"},"finish_reason":"tool_calls","native_finish_reason":"tool_calls"}]}
154
155 data: {"id":"gen-1773004301-OBBlcdTOwgZugkI2ltOq","object":"chat.completion.chunk","created":1773004301,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[],"usage":{"prompt_tokens":14454,"completion_tokens":26,"total_tokens":14480,"cost":0.0029216,"is_byok":false,"prompt_tokens_details":{"cached_tokens":11648,"cache_write_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0029216,"upstream_inference_prompt_cost":0.0028696,"upstream_inference_completions_cost":0.000052},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}
156
157 data: [DONE]
158
159 headers:
160 Content-Type:
161 - text/event-stream
162 status: 200 OK
163 code: 200
164 duration: 910.74ms
165- id: 4
166 request:
167 proto: HTTP/1.1
168 proto_major: 1
169 proto_minor: 1
170 content_length: 441
171 host: sourcegraph.com
172 body: '{"query":"query Search($query: String!) { search(query: $query, version: V2, patternType: keyword ) { results { matchCount, limitHit, resultCount, approximateResultCount, missing { name }, timedout { name }, indexUnavailable, results { __typename, ... on FileMatch { repository { name }, file { path, url, content }, lineMatches { preview, lineNumber, offsetAndLengths } } } } } }","variables":{"query":": \"func main lang:go type:file\"}"}}'
173 headers:
174 Content-Type:
175 - application/json
176 User-Agent:
177 - crush/1.0
178 url: https://sourcegraph.com/.api/graphql
179 method: POST
180 response:
181 proto: HTTP/2.0
182 proto_major: 2
183 proto_minor: 0
184 content_length: -1
185 uncompressed: true
186 body: '{"data":{"search":{"results":{"matchCount":0,"limitHit":false,"resultCount":0,"approximateResultCount":"0","missing":[],"timedout":[],"indexUnavailable":false,"results":[]}}}}'
187 headers:
188 Content-Type:
189 - application/json
190 status: 200 OK
191 code: 200
192 duration: 341.816ms
193- id: 5
194 request:
195 proto: HTTP/1.1
196 proto_major: 1
197 proto_minor: 1
198 content_length: 60147
199 host: ""
200 body: "{\"messages\":[{\"content\":\"You are Crush, a powerful AI Assistant that runs in the CLI.\\n\\n<critical_rules>\\nThese rules override everything else. Follow them strictly:\\n\\n1. **READ BEFORE EDITING**: Never edit a file you haven't already read in this conversation. Once read, you don't need to re-read unless it changed. Pay close attention to exact formatting, indentation, and whitespace - these must match exactly in your edits.\\n2. **BE AUTONOMOUS**: Don't ask questions - search, read, think, decide, act. Break complex tasks into steps and complete them all. Systematically try alternative strategies (different commands, search terms, tools, refactors, or scopes) until either the task is complete or you hit a hard external limit (missing credentials, permissions, files, or network access you cannot change). Only stop for actual blocking errors, not perceived difficulty.\\n3. **TEST AFTER CHANGES**: Run tests immediately after each modification.\\n4. **BE CONCISE**: Keep output concise (default <4 lines), unless explaining complex changes or asked for detail. Conciseness applies to output only, not to thoroughness of work.\\n5. **USE EXACT MATCHES**: When editing, match text exactly including whitespace, indentation, and line breaks.\\n6. **NEVER COMMIT**: Unless user explicitly says \\\"commit\\\".\\n7. **FOLLOW MEMORY FILE INSTRUCTIONS**: If memory files contain specific instructions, preferences, or commands, you MUST follow them.\\n8. **NEVER ADD COMMENTS**: Only add comments if the user asked you to do so. Focus on *why* not *what*. NEVER communicate with the user through code comments.\\n9. **SECURITY FIRST**: Only assist with defensive security tasks. Refuse to create, modify, or improve code that may be used maliciously.\\n10. **NO URL GUESSING**: Only use URLs provided by the user or found in local files.\\n11. **NEVER PUSH TO REMOTE**: Don't push changes to remote repositories unless explicitly asked.\\n12. **DON'T REVERT CHANGES**: Don't revert changes unless they caused errors or the user explicitly asks.\\n13. **TOOL CONSTRAINTS**: Only use documented tools. Never attempt 'apply_patch' or 'apply_diff' - they don't exist. Use 'edit' or 'multiedit' instead.\\n</critical_rules>\\n\\n<communication_style>\\nKeep responses minimal:\\n- Under 4 lines of text (tool use doesn't count)\\n- Conciseness is about **text only**: always fully implement the requested feature, tests, and wiring even if that requires many tool calls.\\n- No preamble (\\\"Here's...\\\", \\\"I'll...\\\")\\n- No postamble (\\\"Let me know...\\\", \\\"Hope this helps...\\\")\\n- One-word answers when possible\\n- No emojis ever\\n- No explanations unless user asks\\n- Never send acknowledgement-only responses; after receiving new context or instructions, immediately continue the task or state the concrete next action you will take.\\n- Use rich Markdown formatting (headings, bullet lists, tables, code fences) for any multi-sentence or explanatory answer; only use plain unformatted text if the user explicitly asks.\\n- Respond ALL sentenses in the same spoken language the prompt was written in.\\n\\nExamples:\\nuser: what is 2+2?\\nassistant: 4\\n\\nuser: list files in src/\\nassistant: [uses ls tool]\\nfoo.c, bar.c, baz.c\\n\\nuser: which file has the foo implementation?\\nassistant: src/foo.c\\n\\nuser: add error handling to the login function\\nassistant: [searches for login, reads file, edits with exact match, runs tests]\\nDone\\n\\nuser: Where are errors from the client handled?\\nassistant: Clients are marked as failed in the `connectToServer` function in src/services/process.go:712.\\n</communication_style>\\n\\n<code_references>\\nWhen referencing specific functions or code locations, use the pattern `file_path:line_number` to help users navigate:\\n- Example: \\\"The error is handled in src/main.go:45\\\"\\n- Example: \\\"See the implementation in pkg/utils/helper.go:123-145\\\"\\n</code_references>\\n\\n<workflow>\\nFor every task, follow this sequence internally (don't narrate it):\\n\\n**Before acting**:\\n- Search codebase for relevant files\\n- Read files to understand current state\\n- Check memory for stored commands\\n- Identify what needs to change\\n- Use `git log` and `git blame` for additional context when needed\\n\\n**While acting**:\\n- Read entire file before editing it\\n- Before editing: verify exact whitespace and indentation from View output\\n- Use exact text for find/replace (include whitespace)\\n- Make one logical change at a time\\n- After each change: run tests\\n- If tests fail: fix immediately\\n- If edit fails: read more context, don't guess - the text must match exactly\\n- Keep going until query is completely resolved before yielding to user\\n- For longer tasks, send brief progress updates (under 10 words) BUT IMMEDIATELY CONTINUE WORKING - progress updates are not stopping points\\n\\n**Before finishing**:\\n- Verify ENTIRE query is resolved (not just first step)\\n- All described next steps must be completed\\n- Cross-check the original prompt and your own mental checklist; if any feasible part remains undone, continue working instead of responding.\\n- Run lint/typecheck if in memory\\n- Verify all changes work\\n- Keep response under 4 lines\\n\\n**Key behaviors**:\\n- Use find_references before changing shared code\\n- Follow existing patterns (check similar files)\\n- If stuck, try different approach (don't repeat failures)\\n- Make decisions yourself (search first, don't ask)\\n- Fix problems at root cause, not surface-level patches\\n- Don't fix unrelated bugs or broken tests (mention them in final message if relevant)\\n</workflow>\\n\\n<decision_making>\\n**Make decisions autonomously** - don't ask when you can:\\n- Search to find the answer\\n- Read files to see patterns\\n- Check similar code\\n- Infer from context\\n- Try most likely approach\\n- When requirements are underspecified but not obviously dangerous, make the most reasonable assumptions based on project patterns and memory files, briefly state them if needed, and proceed instead of waiting for clarification.\\n\\n**Only stop/ask user if**:\\n- Truly ambiguous business requirement\\n- Multiple valid approaches with big tradeoffs\\n- Could cause data loss\\n- Exhausted all attempts and hit actual blocking errors\\n\\n**When requesting information/access**:\\n- Exhaust all available tools, searches, and reasonable assumptions first.\\n- Never say \\\"Need more info\\\" without detail.\\n- In the same message, list each missing item, why it is required, acceptable substitutes, and what you already attempted.\\n- State exactly what you will do once the information arrives so the user knows the next step.\\n\\nWhen you must stop, first finish all unblocked parts of the request, then clearly report: (a) what you tried, (b) exactly why you are blocked, and (c) the minimal external action required. Don't stop just because one path failed—exhaust multiple plausible approaches first.\\n\\n**Never stop for**:\\n- Task seems too large (break it down)\\n- Multiple files to change (change them)\\n- Concerns about \\\"session limits\\\" (no such limits exist)\\n- Work will take many steps (do all the steps)\\n\\nExamples of autonomous decisions:\\n- File location → search for similar files\\n- Test command → check package.json/memory\\n- Code style → read existing code\\n- Library choice → check what's used\\n- Naming → follow existing names\\n</decision_making>\\n\\n<editing_files>\\n**Available edit tools:**\\n- `edit` - Single find/replace in a file\\n- `multiedit` - Multiple find/replace operations in one file\\n- `write` - Create/overwrite entire file\\n\\nNever use `apply_patch` or similar - those tools don't exist.\\n\\nCritical: ALWAYS read files before editing them in this conversation.\\n\\nWhen using edit tools:\\n1. Read the file first - note the EXACT indentation (spaces vs tabs, count)\\n2. Copy the exact text including ALL whitespace, newlines, and indentation\\n3. Include 3-5 lines of context before and after the target\\n4. Verify your old_string would appear exactly once in the file\\n5. If uncertain about whitespace, include more surrounding context\\n6. Verify edit succeeded\\n7. Run tests\\n\\n**Whitespace matters**:\\n- Count spaces/tabs carefully (use View tool line numbers as reference)\\n- Include blank lines if they exist\\n- Match line endings exactly\\n- When in doubt, include MORE context rather than less\\n\\nEfficiency tips:\\n- Don't re-read files after successful edits (tool will fail if it didn't work)\\n- Same applies for making folders, deleting files, etc.\\n\\nCommon mistakes to avoid:\\n- Editing without reading first\\n- Approximate text matches\\n- Wrong indentation (spaces vs tabs, wrong count)\\n- Missing or extra blank lines\\n- Not enough context (text appears multiple times)\\n- Trimming whitespace that exists in the original\\n- Not testing after changes\\n</editing_files>\\n\\n<whitespace_and_exact_matching>\\nThe Edit tool is extremely literal. \\\"Close enough\\\" will fail.\\n\\n**Before every edit**:\\n1. View the file and locate the exact lines to change\\n2. Copy the text EXACTLY including:\\n - Every space and tab\\n - Every blank line\\n - Opening/closing braces position\\n - Comment formatting\\n3. Include enough surrounding lines (3-5) to make it unique\\n4. Double-check indentation level matches\\n\\n**Common failures**:\\n- `func foo() {` vs `func foo(){` (space before brace)\\n- Tab vs 4 spaces vs 2 spaces\\n- Missing blank line before/after\\n- `// comment` vs `//comment` (space after //)\\n- Different number of spaces in indentation\\n\\n**If edit fails**:\\n- View the file again at the specific location\\n- Copy even more context\\n- Check for tabs vs spaces\\n- Verify line endings\\n- Try including the entire function/block if needed\\n- Never retry with guessed changes - get the exact text first\\n</whitespace_and_exact_matching>\\n\\n<task_completion>\\nEnsure every task is implemented completely, not partially or sketched.\\n\\n1. **Think before acting** (for non-trivial tasks)\\n - Identify all components that need changes (models, logic, routes, config, tests, docs)\\n - Consider edge cases and error paths upfront\\n - Form a mental checklist of requirements before making the first edit\\n - This planning happens internally - don't narrate it to the user\\n\\n2. **Implement end-to-end**\\n - Treat every request as complete work: if adding a feature, wire it fully\\n - Update all affected files (callers, configs, tests, docs)\\n - Don't leave TODOs or \\\"you'll also need to...\\\" - do it yourself\\n - No task is too large - break it down and complete all parts\\n - For multi-part prompts, treat each bullet/question as a checklist item and ensure every item is implemented or answered. Partial completion is not an acceptable final state.\\n\\n3. **Verify before finishing**\\n - Re-read the original request and verify each requirement is met\\n - Check for missing error handling, edge cases, or unwired code\\n - Run tests to confirm the implementation works\\n - Only say \\\"Done\\\" when truly done - never stop mid-task\\n</task_completion>\\n\\n<error_handling>\\nWhen errors occur:\\n1. Read complete error message\\n2. Understand root cause (isolate with debug logs or minimal reproduction if needed)\\n3. Try different approach (don't repeat same action)\\n4. Search for similar code that works\\n5. Make targeted fix\\n6. Test to verify\\n7. For each error, attempt at least two or three distinct remediation strategies (search similar code, adjust commands, narrow or widen scope, change approach) before concluding the problem is externally blocked.\\n\\nCommon errors:\\n- Import/Module → check paths, spelling, what exists\\n- Syntax → check brackets, indentation, typos\\n- Tests fail → read test, see what it expects\\n- File not found → use ls, check exact path\\n\\n**Edit tool \\\"old_string not found\\\"**:\\n- View the file again at the target location\\n- Copy the EXACT text including all whitespace\\n- Include more surrounding context (full function if needed)\\n- Check for tabs vs spaces, extra/missing blank lines\\n- Count indentation spaces carefully\\n- Don't retry with approximate matches - get the exact text\\n</error_handling>\\n\\n<memory_instructions>\\nMemory files store commands, preferences, and codebase info. Update them when you discover:\\n- Build/test/lint commands\\n- Code style preferences\\n- Important codebase patterns\\n- Useful project information\\n</memory_instructions>\\n\\n<code_conventions>\\nBefore writing code:\\n1. Check if library exists (look at imports, package.json)\\n2. Read similar code for patterns\\n3. Match existing style\\n4. Use same libraries/frameworks\\n5. Follow security best practices (never log secrets)\\n6. Don't use one-letter variable names unless requested\\n\\nNever assume libraries are available - verify first.\\n\\n**Ambition vs. precision**:\\n- New projects → be creative and ambitious with implementation\\n- Existing codebases → be surgical and precise, respect surrounding code\\n- Don't change filenames or variables unnecessarily\\n- Don't add formatters/linters/tests to codebases that don't have them\\n</code_conventions>\\n\\n<testing>\\nAfter significant changes:\\n- Start testing as specific as possible to code changed, then broaden to build confidence\\n- Use self-verification: write unit tests, add output logs, or use debug statements to verify your solutions\\n- Run relevant test suite\\n- If tests fail, fix before continuing\\n- Check memory for test commands\\n- Run lint/typecheck if available (on precise targets when possible)\\n- For formatters: iterate max 3 times to get it right; if still failing, present correct solution and note formatting issue\\n- Suggest adding commands to memory if not found\\n- Don't fix unrelated bugs or test failures (not your responsibility)\\n</testing>\\n\\n<tool_usage>\\n- Default to using tools (ls, grep, view, agent, tests, web_fetch, etc.) rather than speculation whenever they can reduce uncertainty or unlock progress, even if it takes multiple tool calls.\\n- Search before assuming\\n- Read files before editing\\n- Always use absolute paths for file operations (editing, reading, writing)\\n- Use Agent tool for complex searches\\n- Run tools in parallel when safe (no dependencies)\\n- When making multiple independent bash calls, send them in a single message with multiple tool calls for parallel execution\\n- Summarize tool output for user (they don't see it)\\n- Never use `curl` through the bash tool it is not allowed use the fetch tool instead.\\n- Only use the tools you know exist.\\n\\n<bash_commands>\\n**CRITICAL**: The `description` parameter is REQUIRED for all bash tool calls. Always provide it.\\n\\nWhen running non-trivial bash commands (especially those that modify the system):\\n- Briefly explain what the command does and why you're running it\\n- This ensures the user understands potentially dangerous operations\\n- Simple read-only commands (ls, cat, etc.) don't need explanation\\n- Use `&` for background processes that won't stop on their own (e.g., `node server.js &`)\\n- Avoid interactive commands - use non-interactive versions (e.g., `npm init -y` not `npm init`)\\n- Combine related commands to save time (e.g., `git status && git diff HEAD && git log -n 3`)\\n</bash_commands>\\n</tool_usage>\\n\\n<proactiveness>\\nBalance autonomy with user intent:\\n- When asked to do something → do it fully (including ALL follow-ups and \\\"next steps\\\")\\n- Never describe what you'll do next - just do it\\n- When the user provides new information or clarification, incorporate it immediately and keep executing instead of stopping with an acknowledgement.\\n- Responding with only a plan, outline, or TODO list (or any other purely verbal response) is failure; you must execute the plan via tools whenever execution is possible.\\n- When asked how to approach → explain first, don't auto-implement\\n- After completing work → stop, don't explain (unless asked)\\n- Don't surprise user with unexpected actions\\n</proactiveness>\\n\\n<final_answers>\\nAdapt verbosity to match the work completed:\\n\\n**Default (under 4 lines)**:\\n- Simple questions or single-file changes\\n- Casual conversation, greetings, acknowledgements\\n- One-word answers when possible\\n\\n**More detail allowed (up to 10-15 lines)**:\\n- Large multi-file changes that need walkthrough\\n- Complex refactoring where rationale adds value\\n- Tasks where understanding the approach is important\\n- When mentioning unrelated bugs/issues found\\n- Suggesting logical next steps user might want\\n- Structure longer answers with Markdown sections and lists, and put all code, commands, and config in fenced code blocks.\\n\\n**What to include in verbose answers**:\\n- Brief summary of what was done and why\\n- Key files/functions changed (with `file:line` references)\\n- Any important decisions or tradeoffs made\\n- Next steps or things user should verify\\n- Issues found but not fixed\\n\\n**What to avoid**:\\n- Don't show full file contents unless explicitly asked\\n- Don't explain how to save files or copy code (user has access to your work)\\n- Don't use \\\"Here's what I did\\\" or \\\"Let me know if...\\\" style preambles/postambles\\n- Keep tone direct and factual, like handing off work to a teammate\\n</final_answers>\\n\\n<env>\\nWorking directory: /tmp/crush-test/TestCoderAgent/openrouter-kimi-k2/sourcegraph_tool\\nIs directory a git repo: no\\nPlatform: linux\\nToday's date: 1/1/2025\\n\\n</env>\\n\\n\\n\\n\\n\",\"role\":\"system\",\"cache_control\":{\"type\":\"ephemeral\"}},{\"content\":\"<system_reminder>This is a reminder that your todo list is currently empty. DO NOT mention this to the user explicitly because they are already aware.\\nIf you are working on tasks that would benefit from a todo list please use the \\\"todos\\\" tool to create one.\\nIf not, please feel free to ignore. Again do not mention this message to the user.</system_reminder>\",\"role\":\"user\"},{\"content\":\"use sourcegraph to search for 'func main' in Go repositories\",\"role\":\"user\"},{\"tool_calls\":[{\"id\":\"functions.sourcegraph:0\",\"function\":{\"arguments\":\"{\\\"query\\\": \\\"func main lang:go\\\"}\",\"name\":\"sourcegraph\"},\"type\":\"function\"}],\"role\":\"assistant\"},{\"content\":\"# Sourcegraph Search Results\\n\\nFound 30 matches across 30 results\\n(Result limit reached, try a more specific query)\\n\\n## Result 1: github.com/Balun-courses/deep_go/lessons/functions/defer_with_function/main.go\\n\\nURL: /r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/defer_with_function/main.go\\n\\n```\\n8| }\\n9| \\n10| func handle(string) {\\n11| \\tfmt.Println(\\\"3\\\")\\n12| }\\n13| \\n14| func process() {\\n15| \\tdefer handle(get())\\n16| \\tfmt.Println(\\\"2\\\")\\n17| }\\n18| func main() {\\n19| func main() {\\n20| \\tprocess()\\n21| }\\n22| \\n```\\n\\n```\\n0| package main\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func get() string {\\n6| \\tfmt.Println(\\\"1\\\")\\n7| \\treturn \\\"\\\"\\n8| }\\n9| \\n10| func handle(string) {\\n```\\n\\n```\\n3| import \\\"fmt\\\"\\n4| \\n5| func get() string {\\n6| \\tfmt.Println(\\\"1\\\")\\n7| \\treturn \\\"\\\"\\n8| }\\n9| \\n10| func handle(string) {\\n11| \\tfmt.Println(\\\"3\\\")\\n12| }\\n13| func process() {\\n14| func process() {\\n15| \\tdefer handle(get())\\n16| \\tfmt.Println(\\\"2\\\")\\n17| }\\n18| \\n19| func main() {\\n20| \\tprocess()\\n21| }\\n22| \\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| func get() string {\\n5| func get() string {\\n6| \\tfmt.Println(\\\"1\\\")\\n7| \\treturn \\\"\\\"\\n8| }\\n9| \\n10| func handle(string) {\\n11| \\tfmt.Println(\\\"3\\\")\\n12| }\\n13| \\n14| func process() {\\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func get() string {\\n6| \\tfmt.Println(\\\"1\\\")\\n7| \\treturn \\\"\\\"\\n8| }\\n9| func handle(string) {\\n10| func handle(string) {\\n11| \\tfmt.Println(\\\"3\\\")\\n12| }\\n13| \\n14| func process() {\\n15| \\tdefer handle(get())\\n16| \\tfmt.Println(\\\"2\\\")\\n17| }\\n18| \\n19| func main() {\\n```\\n\\n## Result 2: github.com/Balun-courses/deep_go/lessons/functions/high_order_function/main.go\\n\\nURL: /r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/high_order_function/main.go\\n\\n```\\n3| import \\\"fmt\\\"\\n4| \\n5| func forEach(data []int, fn func(int) int) []int {\\n6| \\tnewData := make([]int, 0, len(data))\\n7| \\tfor _, value := range data {\\n8| \\t\\tnewData = append(newData, fn(value))\\n9| \\t}\\n10| \\n11| \\treturn newData\\n12| }\\n13| func main() {\\n14| func main() {\\n15| \\tvar data = []int{1, 2, 3, 4}\\n16| \\tvar newData = forEach(data, func(value int) int {\\n17| \\t\\treturn (value * value)\\n18| \\t})\\n19| \\n20| \\tfmt.Println(data)\\n21| \\tfmt.Println(newData)\\n22| }\\n23| \\n```\\n\\n```\\n5| func forEach(data []int, fn func(int) int) []int {\\n6| \\tnewData := make([]int, 0, len(data))\\n7| \\tfor _, value := range data {\\n8| \\t\\tnewData = append(newData, fn(value))\\n9| \\t}\\n10| \\n11| \\treturn newData\\n12| }\\n13| \\n14| func main() {\\n15| \\tvar newData = forEach(data, func(value int) int {\\n16| \\tvar newData = forEach(data, func(value int) int {\\n17| \\t\\treturn (value * value)\\n18| \\t})\\n19| \\n20| \\tfmt.Println(data)\\n21| \\tfmt.Println(newData)\\n22| }\\n23| \\n```\\n\\n```\\n0| package main\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func forEach(data []int, fn func(int) int) []int {\\n6| \\tnewData := make([]int, 0, len(data))\\n7| \\tfor _, value := range data {\\n8| \\t\\tnewData = append(newData, fn(value))\\n9| \\t}\\n10| \\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| func forEach(data []int, fn func(int) int) []int {\\n5| func forEach(data []int, fn func(int) int) []int {\\n6| \\tnewData := make([]int, 0, len(data))\\n7| \\tfor _, value := range data {\\n8| \\t\\tnewData = append(newData, fn(value))\\n9| \\t}\\n10| \\n11| \\treturn newData\\n12| }\\n13| \\n14| func main() {\\n```\\n\\n## Result 3: github.com/Balun-courses/deep_go/lessons/functions/composition/main.go\\n\\nURL: /r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/composition/main.go\\n\\n```\\n12| \\n13| func compose(fn ...func(int) int) func(int) int {\\n14| \\treturn func(value int) int {\\n15| \\t\\tfor _, v := range fn {\\n16| \\t\\t\\tvalue = v(value)\\n17| \\t\\t}\\n18| \\n19| \\t\\treturn value\\n20| \\t}\\n21| }\\n22| func main() {\\n23| func main() {\\n24| \\tfn := compose(sqr, neg, sqr)\\n25| \\tfmt.Println(fn(4))\\n26| }\\n27| \\n```\\n\\n```\\n0| package main\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func sqr(number int) int {\\n6| \\treturn number * number\\n7| }\\n8| \\n9| func neg(number int) int {\\n10| \\treturn -number\\n```\\n\\n```\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func sqr(number int) int {\\n6| \\treturn number * number\\n7| }\\n8| \\n9| func neg(number int) int {\\n10| \\treturn -number\\n11| }\\n12| func compose(fn ...func(int) int) func(int) int {\\n13| func compose(fn ...func(int) int) func(int) int {\\n14| \\treturn func(value int) int {\\n15| \\t\\tfor _, v := range fn {\\n16| \\t\\t\\tvalue = v(value)\\n17| \\t\\t}\\n18| \\n19| \\t\\treturn value\\n20| \\t}\\n21| }\\n22| \\n```\\n\\n```\\n3| import \\\"fmt\\\"\\n4| \\n5| func sqr(number int) int {\\n6| \\treturn number * number\\n7| }\\n8| \\n9| func neg(number int) int {\\n10| \\treturn -number\\n11| }\\n12| \\n13| \\treturn func(value int) int {\\n14| \\treturn func(value int) int {\\n15| \\t\\tfor _, v := range fn {\\n16| \\t\\t\\tvalue = v(value)\\n17| \\t\\t}\\n18| \\n19| \\t\\treturn value\\n20| \\t}\\n21| }\\n22| \\n23| func main() {\\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| func sqr(number int) int {\\n5| func sqr(number int) int {\\n6| \\treturn number * number\\n7| }\\n8| \\n9| func neg(number int) int {\\n10| \\treturn -number\\n11| }\\n12| \\n13| func compose(fn ...func(int) int) func(int) int {\\n14| \\treturn func(value int) int {\\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func sqr(number int) int {\\n6| \\treturn number * number\\n7| }\\n8| func neg(number int) int {\\n9| func neg(number int) int {\\n10| \\treturn -number\\n11| }\\n12| \\n13| func compose(fn ...func(int) int) func(int) int {\\n14| \\treturn func(value int) int {\\n15| \\t\\tfor _, v := range fn {\\n16| \\t\\t\\tvalue = v(value)\\n17| \\t\\t}\\n18| \\n```\\n\\n## Result 4: github.com/Balun-courses/deep_go/lessons/functions/defer_evaluation_moment/main.go\\n\\nURL: /r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/defer_evaluation_moment/main.go\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| func main() {\\n5| func main() {\\n6| \\tvar f func()\\n7| \\tdefer f()\\n8| \\n9| \\tf = func() {\\n10| \\t\\tfmt.Println(true)\\n11| \\t}\\n12| }\\n13| \\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| \\tvar f func()\\n6| \\tvar f func()\\n7| \\tdefer f()\\n8| \\n9| \\tf = func() {\\n10| \\t\\tfmt.Println(true)\\n11| \\t}\\n12| }\\n13| \\n```\\n\\n```\\n0| package main\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func main() {\\n6| \\tvar f func()\\n7| \\tdefer f()\\n8| \\n9| \\tf = func() {\\n10| \\t\\tfmt.Println(true)\\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func main() {\\n6| \\tvar f func()\\n7| \\tdefer f()\\n8| \\tf = func() {\\n9| \\tf = func() {\\n10| \\t\\tfmt.Println(true)\\n11| \\t}\\n12| }\\n13| \\n```\\n\\n## Result 5: github.com/Balun-courses/deep_go/lessons/contexts/after_done/main.go\\n\\nURL: /r/github.com/Balun-courses/deep_go/-/blob/lessons/contexts/after_done/main.go\\n\\n```\\n9| // context.AfterFunc\\n10| \\n11| func WithCtxAfterFunc(ctx context.Context, action func()) {\\n12| \\tif action != nil {\\n13| \\t\\tgo func() {\\n14| \\t\\t\\t<-ctx.Done()\\n15| \\t\\t\\taction()\\n16| \\t\\t}()\\n17| \\t}\\n18| }\\n19| func main() {\\n20| func main() {\\n21| \\tctx, cancel := context.WithCancel(context.Background())\\n22| \\tWithCtxAfterFunc(ctx, func() {\\n23| \\t\\tfmt.Println(\\\"after\\\")\\n24| \\t})\\n25| \\n26| \\tcancel()\\n27| \\n28| \\ttime.Sleep(100 * time.Millisecond)\\n29| }\\n```\\n\\n```\\n11| func WithCtxAfterFunc(ctx context.Context, action func()) {\\n12| \\tif action != nil {\\n13| \\t\\tgo func() {\\n14| \\t\\t\\t<-ctx.Done()\\n15| \\t\\t\\taction()\\n16| \\t\\t}()\\n17| \\t}\\n18| }\\n19| \\n20| func main() {\\n21| \\tWithCtxAfterFunc(ctx, func() {\\n22| \\tWithCtxAfterFunc(ctx, func() {\\n23| \\t\\tfmt.Println(\\\"after\\\")\\n24| \\t})\\n25| \\n26| \\tcancel()\\n27| \\n28| \\ttime.Sleep(100 * time.Millisecond)\\n29| }\\n30| \\n```\\n\\n```\\n0| package main\\n1| package main\\n2| \\n3| import (\\n4| \\t\\\"context\\\"\\n5| \\t\\\"fmt\\\"\\n6| \\t\\\"time\\\"\\n7| )\\n8| \\n9| // context.AfterFunc\\n10| \\n```\\n\\n```\\n1| package main\\n2| \\n3| import (\\n4| \\t\\\"context\\\"\\n5| \\t\\\"fmt\\\"\\n6| \\t\\\"time\\\"\\n7| )\\n8| // context.AfterFunc\\n9| // context.AfterFunc\\n10| \\n11| func WithCtxAfterFunc(ctx context.Context, action func()) {\\n12| \\tif action != nil {\\n13| \\t\\tgo func() {\\n14| \\t\\t\\t<-ctx.Done()\\n15| \\t\\t\\taction()\\n16| \\t\\t}()\\n17| \\t}\\n18| }\\n```\\n\\n```\\n1| package main\\n2| \\n3| import (\\n4| \\t\\\"context\\\"\\n5| \\t\\\"fmt\\\"\\n6| \\t\\\"time\\\"\\n7| )\\n8| \\n9| // context.AfterFunc\\n10| func WithCtxAfterFunc(ctx context.Context, action func()) {\\n11| func WithCtxAfterFunc(ctx context.Context, action func()) {\\n12| \\tif action != nil {\\n13| \\t\\tgo func() {\\n14| \\t\\t\\t<-ctx.Done()\\n15| \\t\\t\\taction()\\n16| \\t\\t}()\\n17| \\t}\\n18| }\\n19| \\n20| func main() {\\n```\\n\\n\",\"tool_call_id\":\"functions.sourcegraph:0\",\"role\":\"tool\"},{\"tool_calls\":[{\"id\":\"functions.sourcegraph:1\",\"function\":{\"arguments\":\"{\\\"query\\\": \\\": \\\\\\\"func main lang:go type:file\\\\\\\"}\\\"}\",\"name\":\"sourcegraph\"},\"type\":\"function\",\"cache_control\":{\"type\":\"ephemeral\"}}],\"role\":\"assistant\"},{\"content\":\"# Sourcegraph Search Results\\n\\nFound 0 matches across 0 results\\n\\nNo results found. Try a different query.\\n\",\"tool_call_id\":\"functions.sourcegraph:1\",\"role\":\"tool\"}],\"model\":\"moonshotai/kimi-k2-0905\",\"max_tokens\":10000,\"stream_options\":{\"include_usage\":true},\"tool_choice\":\"auto\",\"tools\":[{\"function\":{\"name\":\"bash\",\"strict\":false,\"description\":\"Executes bash commands with automatic background conversion for long-running tasks.\\n\\n<cross_platform>\\nUses mvdan/sh interpreter (Bash-compatible on all platforms including Windows).\\nUse forward slashes for paths: \\\"ls C:/foo/bar\\\" not \\\"ls C:\\\\foo\\\\bar\\\".\\nCommon shell builtins and core utils available on Windows.\\n</cross_platform>\\n\\n<execution_steps>\\n1. Directory Verification: If creating directories/files, use LS tool to verify parent exists\\n2. Security Check: Banned commands (alias, aria2c, axel, chrome, curl, curlie, firefox, http-prompt, httpie, links, lynx, nc, safari, scp, ssh, telnet, w3m, wget, xh, doas, su, sudo, apk, apt, apt-cache, apt-get, dnf, dpkg, emerge, home-manager, makepkg, opkg, pacman, paru, pkg, pkg_add, pkg_delete, portage, rpm, yay, yum, zypper, at, batch, chkconfig, crontab, fdisk, mkfs, mount, parted, service, systemctl, umount, firewall-cmd, ifconfig, ip, iptables, netstat, pfctl, route, ufw) return error - explain to user. Safe read-only commands execute without prompts\\n3. Command Execution: Execute with proper quoting, capture output\\n4. Auto-Background: Commands exceeding 1 minute automatically move to background and return shell ID\\n5. Output Processing: Truncate if exceeds 30000 characters\\n6. Return Result: Include errors, metadata with <cwd></cwd> tags\\n</execution_steps>\\n\\n<usage_notes>\\n- Command required, working_dir optional (defaults to current directory)\\n- IMPORTANT: Use Grep/Glob/Agent tools instead of 'find'/'grep'. Use View/LS tools instead of 'cat'/'head'/'tail'/'ls'\\n- Chain with ';' or '&&', avoid newlines except in quoted strings\\n- Each command runs in independent shell (no state persistence between calls)\\n- Prefer absolute paths over 'cd' (use 'cd' only if user explicitly requests)\\n</usage_notes>\\n\\n<background_execution>\\n- Set run_in_background=true to run commands in a separate background shell\\n- Returns a shell ID for managing the background process\\n- Use job_output tool to view current output from background shell\\n- Use job_kill tool to terminate a background shell\\n- IMPORTANT: NEVER use `&` at the end of commands to run in background - use run_in_background parameter instead\\n- Commands that should run in background:\\n * Long-running servers (e.g., `npm start`, `python -m http.server`, `node server.js`)\\n * Watch/monitoring tasks (e.g., `npm run watch`, `tail -f logfile`)\\n * Continuous processes that don't exit on their own\\n * Any command expected to run indefinitely\\n- Commands that should NOT run in background:\\n * Build commands (e.g., `npm run build`, `go build`)\\n * Test suites (e.g., `npm test`, `pytest`)\\n * Git operations\\n * File operations\\n * Short-lived scripts\\n</background_execution>\\n\\n<git_commits>\\nWhen user asks to create git commit:\\n\\n1. Single message with three tool_use blocks (IMPORTANT for speed):\\n - git status (untracked files)\\n - git diff (staged/unstaged changes)\\n - git log (recent commit message style)\\n\\n2. Add relevant untracked files to staging. Don't commit files already modified at conversation start unless relevant.\\n\\n3. Analyze staged changes in <commit_analysis> tags:\\n - List changed/added files, summarize nature (feature/enhancement/bug fix/refactoring/test/docs)\\n - Brainstorm purpose/motivation, assess project impact, check for sensitive info\\n - Don't use tools beyond git context\\n - Draft concise (1-2 sentences) message focusing on \\\"why\\\" not \\\"what\\\"\\n - Use clear language, accurate reflection (\\\"add\\\"=new feature, \\\"update\\\"=enhancement, \\\"fix\\\"=bug fix)\\n - Avoid generic messages, review draft\\n\\n4. Create commit with attribution using HEREDOC:\\n git commit -m \\\"$(cat <<'EOF'\\n Commit message here.\\n\\n\\n \U0001F498 Generated with Crush\\n\\n\\n\\n Co-Authored-By: Crush <crush@charm.land>\\n\\n\\n EOF\\n )\\\"\\n\\n5. If pre-commit hook fails, retry ONCE. If fails again, hook preventing commit. If succeeds but files modified, MUST amend.\\n\\n6. Run git status to verify.\\n\\nNotes: Use \\\"git commit -am\\\" when possible, don't stage unrelated files, NEVER update config, don't push, no -i flags, no empty commits, return empty response.\\n</git_commits>\\n\\n<pull_requests>\\nUse gh command for ALL GitHub tasks. When user asks to create PR:\\n\\n1. Single message with multiple tool_use blocks (VERY IMPORTANT for speed):\\n - git status (untracked files)\\n - git diff (staged/unstaged changes)\\n - Check if branch tracks remote and is up to date\\n - git log and 'git diff main...HEAD' (full commit history from main divergence)\\n\\n2. Create new branch if needed\\n3. Commit changes if needed\\n4. Push to remote with -u flag if needed\\n\\n5. Analyze changes in <pr_analysis> tags:\\n - List commits since diverging from main\\n - Summarize nature of changes\\n - Brainstorm purpose/motivation\\n - Assess project impact\\n - Don't use tools beyond git context\\n - Check for sensitive information\\n - Draft concise (1-2 bullet points) PR summary focusing on \\\"why\\\"\\n - Ensure summary reflects ALL changes since main divergence\\n - Clear, concise language\\n - Accurate reflection of changes and purpose\\n - Avoid generic summaries\\n - Review draft\\n\\n6. Create PR with gh pr create using HEREDOC:\\n gh pr create --title \\\"title\\\" --body \\\"$(cat <<'EOF'\\n\\n ## Summary\\n\\n <1-3 bullet points>\\n\\n ## Test plan\\n\\n [Checklist of TODOs...]\\n\\n\\n \U0001F498 Generated with Crush\\n\\n\\n EOF\\n )\\\"\\n\\nImportant:\\n\\n- Return empty response - user sees gh output\\n- Never update git config\\n</pull_requests>\\n\\n<examples>\\nGood: pytest /foo/bar/tests\\nBad: cd /foo/bar && pytest tests\\n</examples>\\n\",\"parameters\":{\"properties\":{\"command\":{\"description\":\"The command to execute\",\"type\":\"string\"},\"description\":{\"description\":\"A brief description of what the command does, try to keep it under 30 characters or so\",\"type\":\"string\"},\"run_in_background\":{\"description\":\"Set to true (boolean) to run this command in the background. Use job_output to read the output later.\",\"type\":\"boolean\"},\"working_dir\":{\"description\":\"The working directory to execute the command in (defaults to current directory)\",\"type\":\"string\"}},\"required\":[\"description\",\"command\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"download\",\"strict\":false,\"description\":\"Downloads binary data from URL and saves to local file.\\n\\n<usage>\\n- Provide URL to download from\\n- Specify local file path where content should be saved\\n- Optional timeout for request\\n</usage>\\n\\n<features>\\n- Downloads any file type (binary or text)\\n- Auto-creates parent directories if missing\\n- Handles large files efficiently with streaming\\n- Sets reasonable timeouts to prevent hanging\\n- Validates input parameters before requests\\n</features>\\n\\n<limitations>\\n- Max file size: 100MB\\n- Only supports HTTP and HTTPS protocols\\n- Cannot handle authentication or cookies\\n- Some websites may block automated requests\\n- Will overwrite existing files without warning\\n</limitations>\\n\\n<tips>\\n- Use absolute paths or paths relative to working directory\\n- Set appropriate timeouts for large files or slow connections\\n</tips>\\n\",\"parameters\":{\"properties\":{\"file_path\":{\"description\":\"The local file path where the downloaded content should be saved\",\"type\":\"string\"},\"timeout\":{\"description\":\"Optional timeout in seconds (max 600)\",\"type\":\"integer\"},\"url\":{\"description\":\"The URL to download from\",\"type\":\"string\"}},\"required\":[\"url\",\"file_path\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"edit\",\"strict\":false,\"description\":\"Edits files by replacing text, creating new files, or deleting content. For moving/renaming use Bash 'mv'. For large edits use Write tool.\\n\\n<prerequisites>\\n1. Use View tool to understand file contents and context\\n2. For new files: Use LS tool to verify parent directory exists\\n3. **CRITICAL**: Note exact whitespace, indentation, and formatting from View output\\n</prerequisites>\\n\\n<parameters>\\n1. file_path: Absolute path to file (required)\\n2. old_string: Text to replace (must match exactly including whitespace/indentation)\\n3. new_string: Replacement text\\n4. replace_all: Replace all occurrences (default false)\\n</parameters>\\n\\n<special_cases>\\n\\n- Create file: provide file_path + new_string, leave old_string empty\\n- Delete content: provide file_path + old_string, leave new_string empty\\n </special_cases>\\n\\n<critical_requirements>\\nEXACT MATCHING: The tool is extremely literal. Text must match **EXACTLY**\\n\\n- Every space and tab character\\n- Every blank line\\n- Every newline character\\n- Indentation level (count the spaces/tabs)\\n- Comment spacing (`// comment` vs `//comment`)\\n- Brace positioning (`func() {` vs `func(){`)\\n\\nCommon failures:\\n\\n```\\nExpected: \\\" func foo() {\\\" (4 spaces)\\nProvided: \\\" func foo() {\\\" (2 spaces) ❌ FAILS\\n\\nExpected: \\\"}\\\\n\\\\nfunc bar() {\\\" (2 newlines)\\nProvided: \\\"}\\\\nfunc bar() {\\\" (1 newline) ❌ FAILS\\n\\nExpected: \\\"// Comment\\\" (space after //)\\nProvided: \\\"//Comment\\\" (no space) ❌ FAILS\\n```\\n\\nUNIQUENESS (when replace_all=false): old_string MUST uniquely identify target instance\\n\\n- Include 3-5 lines context BEFORE and AFTER change point\\n- Include exact whitespace, indentation, surrounding code\\n- If text appears multiple times, add more context to make it unique\\n\\nSINGLE INSTANCE: Tool changes ONE instance when replace_all=false\\n\\n- For multiple instances: set replace_all=true OR make separate calls with unique context\\n- Plan calls carefully to avoid conflicts\\n\\nVERIFICATION BEFORE USING: Before every edit\\n\\n1. View the file and locate exact target location\\n2. Check how many instances of target text exist\\n3. Copy the EXACT text including all whitespace\\n4. Verify you have enough context for unique identification\\n5. Double-check indentation matches (count spaces/tabs)\\n6. Plan separate calls or use replace_all for multiple changes\\n </critical_requirements>\\n\\n<warnings>\\nTool fails if:\\n- old_string matches multiple locations and replace_all=false\\n- old_string doesn't match exactly (including whitespace)\\n- Insufficient context causes wrong instance change\\n- Indentation is off by even one space\\n- Missing or extra blank lines\\n- Wrong tabs vs spaces\\n</warnings>\\n\\n<recovery_steps>\\nIf you get \\\"old_string not found in file\\\":\\n\\n1. **View the file again** at the specific location\\n2. **Copy more context** - include entire function if needed\\n3. **Check whitespace**:\\n - Count indentation spaces/tabs\\n - Look for blank lines\\n - Check for trailing spaces\\n4. **Verify character-by-character** that your old_string matches\\n5. **Never guess** - always View the file to get exact text\\n </recovery_steps>\\n\\n<best_practices>\\n\\n- Ensure edits result in correct, idiomatic code\\n- Don't leave code in broken state\\n- Use absolute file paths (starting with /)\\n- Use forward slashes (/) for cross-platform compatibility\\n- Multiple edits to same file: send all in single message with multiple tool calls\\n- **When in doubt, include MORE context rather than less**\\n- Match the existing code style exactly (spaces, tabs, blank lines)\\n </best_practices>\\n\\n<whitespace_checklist>\\nBefore submitting an edit, verify:\\n\\n- [ ] Viewed the file first\\n- [ ] Counted indentation spaces/tabs\\n- [ ] Included blank lines if they exist\\n- [ ] Matched brace/bracket positioning\\n- [ ] Included 3-5 lines of surrounding context\\n- [ ] Verified text appears exactly once (or using replace_all)\\n- [ ] Copied text character-for-character, not approximated\\n </whitespace_checklist>\\n\\n<examples>\\n✅ Correct: Exact match with context\\n\\n```\\nold_string: \\\"func ProcessData(input string) error {\\\\n if input == \\\\\\\"\\\\\\\" {\\\\n return errors.New(\\\\\\\"empty input\\\\\\\")\\\\n }\\\\n return nil\\\\n}\\\"\\n\\nnew_string: \\\"func ProcessData(input string) error {\\\\n if input == \\\\\\\"\\\\\\\" {\\\\n return errors.New(\\\\\\\"empty input\\\\\\\")\\\\n }\\\\n // New validation\\\\n if len(input) > 1000 {\\\\n return errors.New(\\\\\\\"input too long\\\\\\\")\\\\n }\\\\n return nil\\\\n}\\\"\\n```\\n\\n❌ Incorrect: Not enough context\\n\\n```\\nold_string: \\\"return nil\\\" // Appears many times!\\n```\\n\\n❌ Incorrect: Wrong indentation\\n\\n```\\nold_string: \\\" if input == \\\\\\\"\\\\\\\" {\\\" // 2 spaces\\n// But file actually has: \\\" if input == \\\\\\\"\\\\\\\" {\\\" // 4 spaces\\n```\\n\\n✅ Correct: Including context to make unique\\n\\n```\\nold_string: \\\"func ProcessData(input string) error {\\\\n if input == \\\\\\\"\\\\\\\" {\\\\n return errors.New(\\\\\\\"empty input\\\\\\\")\\\\n }\\\\n return nil\\\"\\n```\\n\\n</examples>\\n\\n<windows_notes>\\n\\n- Forward slashes work throughout (C:/path/file)\\n- File permissions handled automatically\\n- Line endings converted automatically (\\\\n ↔ \\\\r\\\\n)\\n </windows_notes>\\n\",\"parameters\":{\"properties\":{\"file_path\":{\"description\":\"The absolute path to the file to modify\",\"type\":\"string\"},\"new_string\":{\"description\":\"The text to replace it with\",\"type\":\"string\"},\"old_string\":{\"description\":\"The text to replace\",\"type\":\"string\"},\"replace_all\":{\"description\":\"Replace all occurrences of old_string (default false)\",\"type\":\"boolean\"}},\"required\":[\"file_path\",\"old_string\",\"new_string\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"multiedit\",\"strict\":false,\"description\":\"Makes multiple edits to a single file in one operation. Built on Edit tool for efficient multiple find-and-replace operations. Prefer over Edit tool for multiple edits to same file.\\n\\n<prerequisites>\\n1. Use View tool to understand file contents and context\\n2. Verify directory path is correct\\n3. CRITICAL: Note exact whitespace, indentation, and formatting from View output\\n</prerequisites>\\n\\n<parameters>\\n1. file_path: Absolute path to file (required)\\n2. edits: Array of edit operations, each containing:\\n - old_string: Text to replace (must match exactly including whitespace/indentation)\\n - new_string: Replacement text\\n - replace_all: Replace all occurrences (optional, defaults to false)\\n</parameters>\\n\\n<operation>\\n- Edits applied sequentially in provided order.\\n- Each edit operates on result of previous edit.\\n- PARTIAL SUCCESS: If some edits fail, successful edits are still applied. Failed edits are returned in the response.\\n- File is modified if at least one edit succeeds.\\n- Ideal for several changes to different parts of same file.\\n</operation>\\n\\n<inherited_rules>\\nAll instructions from the Edit tool documentation apply verbatim to every edit item:\\n- Critical requirements for exact matching and uniqueness\\n- Warnings and common failures (tabs vs spaces, blank lines, brace placement, etc.)\\n- Verification steps before using, recovery steps, best practices, and whitespace checklist\\nUse the same level of precision as Edit. Multiedit often fails due to formatting mismatches—double-check whitespace for every edit.\\n</inherited_rules>\\n\\n<critical_requirements>\\n1. Apply Edit tool rules to EACH edit (see edit.md).\\n2. Edits are applied in order; successful edits are kept even if later edits fail.\\n3. Plan sequence carefully: earlier edits change the file content that later edits must match.\\n4. Ensure each old_string is unique at its application time (after prior edits).\\n5. Check the response for failed edits and retry them if needed.\\n</critical_requirements>\\n\\n<verification_before_using>\\n1. View the file and copy exact text (including whitespace) for each target.\\n2. Check how many instances each old_string has BEFORE the sequence starts.\\n3. Dry-run mentally: after applying edit #N, will edit #N+1 still match? Adjust old_string/new_string accordingly.\\n4. Prefer fewer, larger context blocks over many tiny fragments that are easy to misalign.\\n5. If edits are independent, consider separate multiedit batches per logical region.\\n</verification_before_using>\\n\\n<warnings>\\n- Operation continues even if some edits fail; check response for failed edits.\\n- Earlier edits can invalidate later matches (added/removed spaces, lines, or reordered text).\\n- Mixed tabs/spaces, trailing spaces, or missing blank lines commonly cause failures.\\n- replace_all may affect unintended regions—use carefully or provide more context.\\n</warnings>\\n\\n<recovery_steps>\\nIf some edits fail:\\n1. Check the response metadata for the list of failed edits with their error messages.\\n2. View the file again to see the current state after successful edits.\\n3. Adjust the failed edits based on the new file content.\\n4. Retry the failed edits with corrected old_string values.\\n5. Consider breaking complex batches into smaller, independent operations.\\n</recovery_steps>\\n\\n<best_practices>\\n- Ensure all edits result in correct, idiomatic code; don't leave code broken.\\n- Use absolute file paths (starting with /).\\n- Use replace_all only when you're certain; otherwise provide unique context.\\n- Match existing style exactly (spaces, tabs, blank lines).\\n- Review failed edits in the response and retry with corrections.\\n</best_practices>\\n\\n<whitespace_checklist>\\nFor EACH edit, verify:\\n- [ ] Viewed the file first\\n- [ ] Counted indentation spaces/tabs\\n- [ ] Included blank lines if present\\n- [ ] Matched brace/bracket positioning\\n- [ ] Included 3–5 lines of surrounding context\\n- [ ] Verified text appears exactly once (or using replace_all deliberately)\\n- [ ] Copied text character-for-character, not approximated\\n</whitespace_checklist>\\n\\n<examples>\\n✅ Correct: Sequential edits where the second match accounts for the first change\\n\\n```\\nedits: [\\n {\\n old_string: \\\"func A() {\\\\n doOld()\\\\n}\\\",\\n new_string: \\\"func A() {\\\\n doNew()\\\\n}\\\",\\n },\\n {\\n // Uses context that still exists AFTER the first replacement\\n old_string: \\\"func B() {\\\\n callA()\\\\n}\\\",\\n new_string: \\\"func B() {\\\\n callA()\\\\n logChange()\\\\n}\\\",\\n },\\n]\\n```\\n\\n❌ Incorrect: Second old_string no longer matches due to whitespace change introduced by the first edit\\n\\n```\\nedits: [\\n {\\n old_string: \\\"func A() {\\\\n doOld()\\\\n}\\\",\\n new_string: \\\"func A() {\\\\n\\\\n doNew()\\\\n}\\\", // Added extra blank line\\n },\\n {\\n old_string: \\\"func A() {\\\\n doNew()\\\\n}\\\", // Missing the new blank line, will FAIL\\n new_string: \\\"func A() {\\\\n doNew()\\\\n logChange()\\\\n}\\\",\\n },\\n]\\n```\\n\\n✅ Correct: Handling partial success\\n\\n```\\n// If edit 2 fails, edit 1 is still applied\\n// Response will indicate:\\n// - edits_applied: 1\\n// - edits_failed: [{index: 2, error: \\\"...\\\", edit: {...}}]\\n// You can then retry edit 2 with corrected context\\n```\\n</examples>\\n\",\"parameters\":{\"properties\":{\"edits\":{\"description\":\"Array of edit operations to perform sequentially on the file\",\"items\":{\"properties\":{\"new_string\":{\"description\":\"The text to replace it with\",\"type\":\"string\"},\"old_string\":{\"description\":\"The text to replace\",\"type\":\"string\"},\"replace_all\":{\"description\":\"Replace all occurrences of old_string (default false).\",\"type\":\"boolean\"}},\"required\":[\"old_string\",\"new_string\"],\"type\":\"object\"},\"type\":\"array\"},\"file_path\":{\"description\":\"The absolute path to the file to modify\",\"type\":\"string\"}},\"required\":[\"file_path\",\"edits\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"fetch\",\"strict\":false,\"description\":\"Fetches raw content from URL and returns it in specified format without any AI processing.\\n\\n<when_to_use>\\nUse this tool when you need:\\n- Raw, unprocessed content from a URL\\n- Direct access to API responses or JSON data\\n- HTML/text/markdown content without interpretation\\n- Simple, fast content retrieval without analysis\\n- To save tokens by avoiding AI processing\\n\\nDO NOT use this tool when you need to:\\n- Extract specific information from a webpage (use agentic_fetch instead)\\n- Answer questions about web content (use agentic_fetch instead)\\n- Analyze or summarize web pages (use agentic_fetch instead)\\n</when_to_use>\\n\\n<usage>\\n- Provide URL to fetch content from\\n- Specify desired output format (text, markdown, or html)\\n- Optional timeout for request\\n</usage>\\n\\n<features>\\n- Supports three output formats: text, markdown, html\\n- Auto-handles HTTP redirects\\n- Fast and lightweight - no AI processing\\n- Sets reasonable timeouts to prevent hanging\\n- Validates input parameters before requests\\n</features>\\n\\n<limitations>\\n- Max response size: 5MB\\n- Only supports HTTP and HTTPS protocols\\n- Cannot handle authentication or cookies\\n- Some websites may block automated requests\\n- Returns raw content only - no analysis or extraction\\n</limitations>\\n\\n<tips>\\n- Use text format for plain text content or simple API responses\\n- Use markdown format for content that should be rendered with formatting\\n- Use html format when you need raw HTML structure\\n- Set appropriate timeouts for potentially slow websites\\n- If the user asks to analyze or extract from a page, use agentic_fetch instead\\n</tips>\\n\",\"parameters\":{\"properties\":{\"format\":{\"description\":\"The format to return the content in (text, markdown, or html)\",\"type\":\"string\"},\"timeout\":{\"description\":\"Optional timeout in seconds (max 120)\",\"type\":\"integer\"},\"url\":{\"description\":\"The URL to fetch content from\",\"type\":\"string\"}},\"required\":[\"url\",\"format\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"glob\",\"strict\":false,\"description\":\"Fast file pattern matching tool that finds files by name/pattern, returning paths sorted by modification time (newest first).\\n\\n<usage>\\n- Provide glob pattern to match against file paths\\n- Optional starting directory (defaults to current working directory)\\n- Results sorted with most recently modified files first\\n</usage>\\n\\n<pattern_syntax>\\n- '\\\\*' matches any sequence of non-separator characters\\n- '\\\\*\\\\*' matches any sequence including separators\\n- '?' matches any single non-separator character\\n- '[...]' matches any character in brackets\\n- '[!...]' matches any character not in brackets\\n</pattern_syntax>\\n\\n<examples>\\n- '*.js' - JavaScript files in current directory\\n- '**/*.js' - JavaScript files in any subdirectory\\n- 'src/**/*.{ts,tsx}' - TypeScript files in src directory\\n- '*.{html,css,js}' - HTML, CSS, and JS files\\n</examples>\\n\\n<limitations>\\n- Results limited to 100 files (newest first)\\n- Does not search file contents (use Grep for that)\\n- Hidden files (starting with '.') skipped\\n</limitations>\\n\\n<cross_platform>\\n- Path separators handled automatically (/ and \\\\ work)\\n- Uses ripgrep (rg) if available, otherwise Go implementation\\n- Patterns should use forward slashes (/) for compatibility\\n</cross_platform>\\n\\n<tips>\\n- Combine with Grep: find files with Glob, search contents with Grep\\n- For iterative exploration requiring multiple searches, consider Agent tool\\n- Check if results truncated and refine pattern if needed\\n</tips>\\n\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The directory to search in. Defaults to the current working directory.\",\"type\":\"string\"},\"pattern\":{\"description\":\"The glob pattern to match files against\",\"type\":\"string\"}},\"required\":[\"pattern\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"grep\",\"strict\":false,\"description\":\"Fast content search tool that finds files containing specific text/patterns, returning matching paths sorted by modification time (newest first).\\n\\n<usage>\\n- Provide regex pattern to search within file contents\\n- Set literal_text=true for exact text with special characters (recommended for non-regex users)\\n- Optional starting directory (defaults to current working directory)\\n- Optional include pattern to filter which files to search\\n- Results sorted with most recently modified files first\\n</usage>\\n\\n<regex_syntax>\\nWhen literal_text=false (supports standard regex):\\n\\n- 'function' searches for literal text \\\"function\\\"\\n- 'log\\\\..\\\\*Error' finds text starting with \\\"log.\\\" and ending with \\\"Error\\\"\\n- 'import\\\\s+.\\\\*\\\\s+from' finds import statements in JavaScript/TypeScript\\n</regex_syntax>\\n\\n<include_patterns>\\n- '\\\\*.js' - Only search JavaScript files\\n- '\\\\*.{ts,tsx}' - Only search TypeScript files\\n- '\\\\*.go' - Only search Go files\\n</include_patterns>\\n\\n<limitations>\\n- Results limited to 100 files (newest first)\\n- Performance depends on number of files searched\\n- Very large binary files may be skipped\\n- Hidden files (starting with '.') skipped\\n</limitations>\\n\\n<ignore_support>\\n- Respects .gitignore patterns to skip ignored files/directories\\n- Respects .crushignore patterns for additional ignore rules\\n- Both ignore files auto-detected in search root directory\\n</ignore_support>\\n\\n<cross_platform>\\n- Uses ripgrep (rg) if available for better performance\\n- Falls back to Go implementation if ripgrep unavailable\\n- File paths normalized automatically for compatibility\\n</cross_platform>\\n\\n<tips>\\n- For faster searches: use Glob to find relevant files first, then Grep\\n- For iterative exploration requiring multiple searches, consider Agent tool\\n- Check if results truncated and refine search pattern if needed\\n- Use literal_text=true for exact text with special characters (dots, parentheses, etc.)\\n</tips>\\n\",\"parameters\":{\"properties\":{\"include\":{\"description\":\"File pattern to include in the search (e.g. \\\"*.js\\\", \\\"*.{ts,tsx}\\\")\",\"type\":\"string\"},\"literal_text\":{\"description\":\"If true, the pattern will be treated as literal text with special regex characters escaped. Default is false.\",\"type\":\"boolean\"},\"path\":{\"description\":\"The directory to search in. Defaults to the current working directory.\",\"type\":\"string\"},\"pattern\":{\"description\":\"The regex pattern to search for in file contents\",\"type\":\"string\"}},\"required\":[\"pattern\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"ls\",\"strict\":false,\"description\":\"Shows files and subdirectories in tree structure for exploring project organization.\\n\\n<usage>\\n- Provide path to list (defaults to current working directory)\\n- Optional glob patterns to ignore\\n- Results displayed in tree structure\\n</usage>\\n\\n<features>\\n- Hierarchical view of files and directories\\n- Auto-skips hidden files/directories (starting with '.')\\n- Skips common system directories like __pycache__\\n- Can filter files matching specific patterns\\n</features>\\n\\n<limitations>\\n- Results limited to 1000 files\\n- Large directories truncated\\n- No file sizes or permissions shown\\n- Cannot recursively list all directories in large projects\\n</limitations>\\n\\n<cross_platform>\\n- Hidden file detection uses Unix convention (files starting with '.')\\n- Windows hidden files (with hidden attribute) not auto-skipped\\n- Common Windows directories (System32, Program Files) not in default ignore\\n- Path separators handled automatically (/ and \\\\ work)\\n</cross_platform>\\n\\n<tips>\\n- Use Glob for finding files by name patterns instead of browsing\\n- Use Grep for searching file contents\\n- Combine with other tools for effective exploration\\n</tips>\\n\",\"parameters\":{\"properties\":{\"depth\":{\"description\":\"The maximum depth to traverse\",\"type\":\"integer\"},\"ignore\":{\"description\":\"List of glob patterns to ignore\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"path\":{\"description\":\"The path to the directory to list (defaults to current working directory)\",\"type\":\"string\"}},\"required\":[],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"sourcegraph\",\"strict\":false,\"description\":\"Search code across public repositories using Sourcegraph's GraphQL API.\\n\\n<usage>\\n- Provide search query using Sourcegraph syntax\\n- Optional result count (default: 10, max: 20)\\n- Optional timeout for request\\n</usage>\\n\\n<basic_syntax>\\n- \\\"fmt.Println\\\" - exact matches\\n- \\\"file:.go fmt.Println\\\" - limit to Go files\\n- \\\"repo:^github\\\\.com/golang/go$ fmt.Println\\\" - specific repos\\n- \\\"lang:go fmt.Println\\\" - limit to Go code\\n- \\\"fmt.Println AND log.Fatal\\\" - combined terms\\n- \\\"fmt\\\\.(Print|Printf|Println)\\\" - regex patterns\\n- \\\"\\\\\\\"exact phrase\\\\\\\"\\\" - exact phrase matching\\n- \\\"-file:test\\\" or \\\"-repo:forks\\\" - exclude matches\\n</basic_syntax>\\n\\n<key_filters>\\nRepository: repo:name, repo:^exact$, repo:org/repo@branch, -repo:exclude, fork:yes, archived:yes, visibility:public\\nFile: file:\\\\.js$, file:internal/, -file:test, file:has.content(text)\\nContent: content:\\\"exact\\\", -content:\\\"unwanted\\\", case:yes\\nType: type:symbol, type:file, type:path, type:diff, type:commit\\nTime: after:\\\"1 month ago\\\", before:\\\"2023-01-01\\\", author:name, message:\\\"fix\\\"\\nResult: select:repo, select:file, select:content, count:100, timeout:30s\\n</key_filters>\\n\\n<examples>\\n- \\\"file:.go context.WithTimeout\\\" - Go code using context.WithTimeout\\n- \\\"lang:typescript useState type:symbol\\\" - TypeScript React useState hooks\\n- \\\"repo:^github\\\\.com/kubernetes/kubernetes$ pod list type:file\\\" - Kubernetes pod files\\n- \\\"file:Dockerfile (alpine OR ubuntu) -content:alpine:latest\\\" - Dockerfiles with base images\\n</examples>\\n\\n<boolean_operators>\\n- \\\"term1 AND term2\\\" - both terms\\n- \\\"term1 OR term2\\\" - either term\\n- \\\"term1 NOT term2\\\" - term1 but not term2\\n- \\\"term1 and (term2 or term3)\\\" - grouping with parentheses\\n</boolean_operators>\\n\\n<limitations>\\n- Only searches public repositories\\n- Rate limits may apply\\n- Complex queries take longer\\n- Max 20 results per query\\n</limitations>\\n\\n<tips>\\n- Use specific file extensions to narrow results\\n- Add repo: filters for targeted searches\\n- Use type:symbol for function/method definitions\\n- Use type:file to find relevant files\\n</tips>\\n\",\"parameters\":{\"properties\":{\"context_window\":{\"description\":\"The context around the match to return (default: 10 lines)\",\"type\":\"integer\"},\"count\":{\"description\":\"Optional number of results to return (default: 10, max: 20)\",\"type\":\"integer\"},\"query\":{\"description\":\"The Sourcegraph search query\",\"type\":\"string\"},\"timeout\":{\"description\":\"Optional timeout in seconds (max 120)\",\"type\":\"integer\"}},\"required\":[\"query\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"view\",\"strict\":false,\"description\":\"Reads and displays file contents with line numbers for examining code, logs, or text data.\\n\\n<usage>\\n- Provide file path to read\\n- Optional offset: start reading from specific line (0-based)\\n- Optional limit: control lines read (default 2000)\\n- Don't use for directories (use LS tool instead)\\n- Supports image files (PNG, JPEG, GIF, BMP, SVG, WebP)\\n</usage>\\n\\n<features>\\n- Displays contents with line numbers\\n- Can read from any file position using offset\\n- Handles large files by limiting lines read\\n- Auto-truncates very long lines for display\\n- Suggests similar filenames when file not found\\n- Renders image files directly in terminal\\n</features>\\n\\n<limitations>\\n- Max file size: 5MB\\n- Default limit: 2000 lines\\n- Lines >2000 chars truncated\\n- Binary files (except images) cannot be displayed\\n</limitations>\\n\\n<cross_platform>\\n- Handles Windows (CRLF) and Unix (LF) line endings\\n- Works with forward slashes (/) and backslashes (\\\\)\\n- Auto-detects text encoding for common formats\\n</cross_platform>\\n\\n<tips>\\n- Use with Glob to find files first\\n- For code exploration: Grep to find relevant files, then View to examine\\n- For large files: use offset parameter for specific sections\\n- View tool automatically detects and renders image files\\n</tips>\\n\",\"parameters\":{\"properties\":{\"file_path\":{\"description\":\"The path to the file to read\",\"type\":\"string\"},\"limit\":{\"description\":\"The number of lines to read (defaults to 2000)\",\"type\":\"integer\"},\"offset\":{\"description\":\"The line number to start reading from (0-based)\",\"type\":\"integer\"}},\"required\":[\"file_path\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"write\",\"strict\":false,\"description\":\"Creates or updates files in filesystem for saving/modifying text content.\\n\\n<usage>\\n- Provide file path to write\\n- Include content to write to file\\n- Tool creates necessary parent directories automatically\\n</usage>\\n\\n<features>\\n- Creates new files or overwrites existing ones\\n- Auto-creates parent directories if missing\\n- Checks if file modified since last read for safety\\n- Avoids unnecessary writes when content unchanged\\n</features>\\n\\n<limitations>\\n- Read file before writing to avoid conflicts\\n- Cannot append (rewrites entire file)\\n</limitations>\\n\\n<cross_platform>\\n- Use forward slashes (/) for compatibility\\n</cross_platform>\\n\\n<tips>\\n- Use View tool first to examine existing files before modifying\\n- Use LS tool to verify location when creating new files\\n- Combine with Glob/Grep to find and modify multiple files\\n- Include descriptive comments when changing existing code\\n</tips>\\n\",\"parameters\":{\"properties\":{\"content\":{\"description\":\"The content to write to the file\",\"type\":\"string\"},\"file_path\":{\"description\":\"The path to the file to write\",\"type\":\"string\"}},\"required\":[\"file_path\",\"content\"],\"type\":\"object\"}},\"type\":\"function\"}],\"usage\":{\"include\":true},\"stream\":true}"
201 headers:
202 Accept:
203 - application/json
204 Content-Type:
205 - application/json
206 User-Agent:
207 - OpenAI/Go 2.7.1
208 url: https://openrouter.ai/api/v1/chat/completions
209 method: POST
210 response:
211 proto: HTTP/2.0
212 proto_major: 2
213 proto_minor: 0
214 content_length: -1
215 body: |+
216 data: {"id":"gen-1773004304-BybFTAEXvo329c2OrYzP","object":"chat.completion.chunk","created":1773004304,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":null,"role":"assistant","tool_calls":[{"index":0,"id":"functions.sourcegraph:2","type":"function","function":{"name":"sourcegraph","arguments":""}}]},"finish_reason":null,"native_finish_reason":null}]}
217
218 data: {"id":"gen-1773004304-BybFTAEXvo329c2OrYzP","object":"chat.completion.chunk","created":1773004304,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":null,"role":"assistant","tool_calls":[{"index":0,"function":{"arguments":"{\"query\": \":E\"}"}}]},"finish_reason":null,"native_finish_reason":null}]}
219
220 data: {"id":"gen-1773004304-BybFTAEXvo329c2OrYzP","object":"chat.completion.chunk","created":1773004304,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"","role":"assistant"},"finish_reason":"tool_calls","native_finish_reason":"tool_calls"}]}
221
222 data: {"id":"gen-1773004304-BybFTAEXvo329c2OrYzP","object":"chat.completion.chunk","created":1773004304,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[],"usage":{"prompt_tokens":14521,"completion_tokens":16,"total_tokens":14537,"cost":0.0022244,"is_byok":false,"prompt_tokens_details":{"cached_tokens":14464,"cache_write_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0022244,"upstream_inference_prompt_cost":0.0021924,"upstream_inference_completions_cost":0.000032},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}
223
224 data: [DONE]
225
226 headers:
227 Content-Type:
228 - text/event-stream
229 status: 200 OK
230 code: 200
231 duration: 649.270125ms
232- id: 6
233 request:
234 proto: HTTP/1.1
235 proto_major: 1
236 proto_minor: 1
237 content_length: 409
238 host: sourcegraph.com
239 body: '{"query":"query Search($query: String!) { search(query: $query, version: V2, patternType: keyword ) { results { matchCount, limitHit, resultCount, approximateResultCount, missing { name }, timedout { name }, indexUnavailable, results { __typename, ... on FileMatch { repository { name }, file { path, url, content }, lineMatches { preview, lineNumber, offsetAndLengths } } } } } }","variables":{"query":":E"}}'
240 headers:
241 Content-Type:
242 - application/json
243 User-Agent:
244 - crush/1.0
245 url: https://sourcegraph.com/.api/graphql
246 method: POST
247 response:
248 proto: HTTP/2.0
249 proto_major: 2
250 proto_minor: 0
251 content_length: -1
252 uncompressed: true
253 body: '{"data":{"search":{"results":{"matchCount":30,"limitHit":true,"resultCount":30,"approximateResultCount":"30+","missing":[],"timedout":[],"indexUnavailable":false,"results":[{"__typename":"FileMatch","repository":{"name":"github.com/astral-sh/uv"},"file":{"path":"crates/uv-distribution/src/error.rs","url":"/r/github.com/astral-sh/uv/-/blob/crates/uv-distribution/src/error.rs","content":"use std::path::PathBuf;\n\nuse owo_colors::OwoColorize;\nuse tokio::task::JoinError;\nuse zip::result::ZipError;\n\nuse crate::metadata::MetadataError;\nuse uv_cache::Error as CacheError;\nuse uv_client::WrappedReqwestError;\nuse uv_distribution_filename::{WheelFilename, WheelFilenameError};\nuse uv_distribution_types::{InstalledDist, InstalledDistError, IsBuildBackendError};\nuse uv_fs::Simplified;\nuse uv_git::GitError;\nuse uv_normalize::PackageName;\nuse uv_pep440::{Version, VersionSpecifiers};\nuse uv_platform_tags::Platform;\nuse uv_pypi_types::{HashAlgorithm, HashDigest};\nuse uv_redacted::DisplaySafeUrl;\nuse uv_types::AnyErrorBuild;\n\n#[derive(Debug, thiserror::Error)]\npub enum Error {\n #[error(\"Building source distributions is disabled\")]\n NoBuild,\n\n // Network error\n #[error(transparent)]\n InvalidUrl(#[from] uv_distribution_types::ToUrlError),\n #[error(\"Expected a file URL, but received: {0}\")]\n NonFileUrl(DisplaySafeUrl),\n #[error(transparent)]\n Git(#[from] uv_git::GitResolverError),\n #[error(transparent)]\n Reqwest(#[from] WrappedReqwestError),\n #[error(transparent)]\n Client(#[from] uv_client::Error),\n\n // Cache writing error\n #[error(\"Failed to read from the distribution cache\")]\n CacheRead(#[source] std::io::Error),\n #[error(\"Failed to write to the distribution cache\")]\n CacheWrite(#[source] std::io::Error),\n #[error(\"Failed to acquire lock on the distribution cache\")]\n CacheLock(#[source] CacheError),\n #[error(\"Failed to deserialize cache entry\")]\n CacheDecode(#[from] rmp_serde::decode::Error),\n #[error(\"Failed to serialize cache entry\")]\n CacheEncode(#[from] rmp_serde::encode::Error),\n #[error(\"Failed to walk the distribution cache\")]\n CacheWalk(#[source] walkdir::Error),\n #[error(transparent)]\n CacheInfo(#[from] uv_cache_info::CacheInfoError),\n\n // Build error\n #[error(transparent)]\n Build(AnyErrorBuild),\n #[error(\"Built wheel has an invalid filename\")]\n WheelFilename(#[from] WheelFilenameError),\n #[error(\"Package metadata name `{metadata}` does not match given name `{given}`\")]\n WheelMetadataNameMismatch {\n given: PackageName,\n metadata: PackageName,\n },\n #[error(\"Package metadata version `{metadata}` does not match given version `{given}`\")]\n WheelMetadataVersionMismatch { given: Version, metadata: Version },\n #[error(\n \"Package metadata name `{metadata}` does not match `{filename}` from the wheel filename\"\n )]\n WheelFilenameNameMismatch {\n filename: PackageName,\n metadata: PackageName,\n },\n #[error(\n \"Package metadata version `{metadata}` does not match `{filename}` from the wheel filename\"\n )]\n WheelFilenameVersionMismatch {\n filename: Version,\n metadata: Version,\n },\n /// This shouldn''t happen, it''s a bug in the build backend.\n #[error(\n \"The built wheel `{}` is not compatible with the current Python {}.{} on {} {}\",\n filename,\n python_version.0,\n python_version.1,\n python_platform.os(),\n python_platform.arch(),\n )]\n BuiltWheelIncompatibleHostPlatform {\n filename: WheelFilename,\n python_platform: Platform,\n python_version: (u8, u8),\n },\n /// This may happen when trying to cross-install native dependencies without their build backend\n /// being aware that the target is a cross-install.\n #[error(\n \"The built wheel `{}` is not compatible with the target Python {}.{} on {} {}. Consider using `--no-build` to disable building wheels.\",\n filename,\n python_version.0,\n python_version.1,\n python_platform.os(),\n python_platform.arch(),\n )]\n BuiltWheelIncompatibleTargetPlatform {\n filename: WheelFilename,\n python_platform: Platform,\n python_version: (u8, u8),\n },\n #[error(\"Failed to parse metadata from built wheel\")]\n Metadata(#[from] uv_pypi_types::MetadataError),\n #[error(\"Failed to read metadata: `{}`\", _0.user_display())]\n WheelMetadata(PathBuf, #[source] Box\u003cuv_metadata::Error\u003e),\n #[error(\"Failed to read metadata from installed package `{0}`\")]\n ReadInstalled(Box\u003cInstalledDist\u003e, #[source] InstalledDistError),\n #[error(\"Failed to read zip archive from built wheel\")]\n Zip(#[from] ZipError),\n #[error(\"Failed to extract archive: {0}\")]\n Extract(String, #[source] uv_extract::Error),\n #[error(\"The source distribution is missing a `PKG-INFO` file\")]\n MissingPkgInfo,\n #[error(\"The source distribution `{}` has no subdirectory `{}`\", _0, _1.display())]\n MissingSubdirectory(DisplaySafeUrl, PathBuf),\n #[error(\"The source distribution `{0}` is missing Git LFS artifacts.\")]\n MissingGitLfsArtifacts(DisplaySafeUrl, #[source] GitError),\n #[error(\"Failed to extract static metadata from `PKG-INFO`\")]\n PkgInfo(#[source] uv_pypi_types::MetadataError),\n #[error(\"The source distribution is missing a `pyproject.toml` file\")]\n MissingPyprojectToml,\n #[error(\"Failed to extract static metadata from `pyproject.toml`\")]\n PyprojectToml(#[source] uv_pypi_types::MetadataError),\n #[error(transparent)]\n MetadataLowering(#[from] MetadataError),\n #[error(\"Distribution not found at: {0}\")]\n NotFound(DisplaySafeUrl),\n #[error(\"Attempted to re-extract the source distribution for `{}`, but the {} hash didn''t match. Run `{}` to clear the cache.\", _0, _1, \"uv cache clean\".green())]\n CacheHeal(String, HashAlgorithm),\n #[error(\"The source distribution requires Python {0}, but {1} is installed\")]\n RequiresPython(VersionSpecifiers, Version),\n #[error(\"Failed to identify base Python interpreter\")]\n BaseInterpreter(#[source] std::io::Error),\n\n /// A generic request middleware error happened while making a request.\n /// Refer to the error message for more details.\n #[error(transparent)]\n ReqwestMiddlewareError(#[from] anyhow::Error),\n\n /// Should not occur; only seen when another task panicked.\n #[error(\"The task executor is broken, did some other task panic?\")]\n Join(#[from] JoinError),\n\n /// An I/O error that occurs while exhausting a reader to compute a hash.\n #[error(\"Failed to hash distribution\")]\n HashExhaustion(#[source] std::io::Error),\n\n #[error(\"Hash mismatch for `{distribution}`\\n\\nExpected:\\n{expected}\\n\\nComputed:\\n{actual}\")]\n MismatchedHashes {\n distribution: String,\n expected: String,\n actual: String,\n },\n\n #[error(\n \"Hash-checking is enabled, but no hashes were provided or computed for: `{distribution}`\"\n )]\n MissingHashes { distribution: String },\n\n #[error(\n \"Hash-checking is enabled, but no hashes were computed for: `{distribution}`\\n\\nExpected:\\n{expected}\"\n )]\n MissingActualHashes {\n distribution: String,\n expected: String,\n },\n\n #[error(\n \"Hash-checking is enabled, but no hashes were provided for: `{distribution}`\\n\\nComputed:\\n{actual}\"\n )]\n MissingExpectedHashes {\n distribution: String,\n actual: String,\n },\n\n #[error(\"Hash-checking is not supported for local directories: `{0}`\")]\n HashesNotSupportedSourceTree(String),\n\n #[error(\"Hash-checking is not supported for Git repositories: `{0}`\")]\n HashesNotSupportedGit(String),\n}\n\nimpl From\u003creqwest::Error\u003e for Error {\n fn from(error: reqwest::Error) -\u003e Self {\n Self::Reqwest(WrappedReqwestError::from(error))\n }\n}\n\nimpl From\u003creqwest_middleware::Error\u003e for Error {\n fn from(error: reqwest_middleware::Error) -\u003e Self {\n match error {\n reqwest_middleware::Error::Middleware(error) =\u003e Self::ReqwestMiddlewareError(error),\n reqwest_middleware::Error::Reqwest(error) =\u003e {\n Self::Reqwest(WrappedReqwestError::from(error))\n }\n }\n }\n}\n\nimpl IsBuildBackendError for Error {\n fn is_build_backend_error(\u0026self) -\u003e bool {\n match self {\n Self::Build(err) =\u003e err.is_build_backend_error(),\n _ =\u003e false,\n }\n }\n}\n\nimpl Error {\n /// Construct a hash mismatch error.\n pub fn hash_mismatch(\n distribution: String,\n expected: \u0026[HashDigest],\n actual: \u0026[HashDigest],\n ) -\u003e Self {\n match (expected.is_empty(), actual.is_empty()) {\n (true, true) =\u003e Self::MissingHashes { distribution },\n (true, false) =\u003e {\n let actual = actual\n .iter()\n .map(|hash| format!(\" {hash}\"))\n .collect::\u003cVec\u003c_\u003e\u003e()\n .join(\"\\n\");\n\n Self::MissingExpectedHashes {\n distribution,\n actual,\n }\n }\n (false, true) =\u003e {\n let expected = expected\n .iter()\n .map(|hash| format!(\" {hash}\"))\n .collect::\u003cVec\u003c_\u003e\u003e()\n .join(\"\\n\");\n\n Self::MissingActualHashes {\n distribution,\n expected,\n }\n }\n (false, false) =\u003e {\n let expected = expected\n .iter()\n .map(|hash| format!(\" {hash}\"))\n .collect::\u003cVec\u003c_\u003e\u003e()\n .join(\"\\n\");\n\n let actual = actual\n .iter()\n .map(|hash| format!(\" {hash}\"))\n .collect::\u003cVec\u003c_\u003e\u003e()\n .join(\"\\n\");\n\n Self::MismatchedHashes {\n distribution,\n expected,\n actual,\n }\n }\n }\n }\n}\n"},"lineMatches":[{"preview":"impl From\u003creqwest::Error\u003e for Error {","lineNumber":189,"offsetAndLengths":[[18,2]]},{"preview":" fn from(error: reqwest::Error) -\u003e Self {","lineNumber":190,"offsetAndLengths":[[27,2]]},{"preview":"use uv_cache::Error as CacheError;","lineNumber":7,"offsetAndLengths":[[13,2]]},{"preview":"#[derive(Debug, thiserror::Error)]","lineNumber":20,"offsetAndLengths":[[26,2]]},{"preview":" Client(#[from] uv_client::Error),","lineNumber":35,"offsetAndLengths":[[29,2]]},{"preview":" CacheRead(#[source] std::io::Error),","lineNumber":39,"offsetAndLengths":[[32,2]]},{"preview":" CacheWrite(#[source] std::io::Error),","lineNumber":41,"offsetAndLengths":[[33,2]]},{"preview":" CacheDecode(#[from] rmp_serde::decode::Error),","lineNumber":45,"offsetAndLengths":[[42,2]]},{"preview":" CacheEncode(#[from] rmp_serde::encode::Error),","lineNumber":47,"offsetAndLengths":[[34,2],[42,2]]},{"preview":" CacheWalk(#[source] walkdir::Error),","lineNumber":49,"offsetAndLengths":[[32,2]]},{"preview":" WheelMetadata(PathBuf, #[source] Box\u003cuv_metadata::Error\u003e),","lineNumber":111,"offsetAndLengths":[[53,2]]},{"preview":" Extract(String, #[source] uv_extract::Error),","lineNumber":117,"offsetAndLengths":[[41,2]]},{"preview":" BaseInterpreter(#[source] std::io::Error),","lineNumber":139,"offsetAndLengths":[[38,2]]},{"preview":" ReqwestMiddlewareError(#[from] anyhow::Error),","lineNumber":144,"offsetAndLengths":[[42,2]]},{"preview":" HashExhaustion(#[source] std::io::Error),","lineNumber":152,"offsetAndLengths":[[37,2]]},{"preview":"impl From\u003creqwest_middleware::Error\u003e for Error {","lineNumber":195,"offsetAndLengths":[[29,2]]},{"preview":" fn from(error: reqwest_middleware::Error) -\u003e Self {","lineNumber":196,"offsetAndLengths":[[38,2]]},{"preview":" reqwest_middleware::Error::Middleware(error) =\u003e Self::ReqwestMiddlewareError(error),","lineNumber":198,"offsetAndLengths":[[31,2]]},{"preview":" reqwest_middleware::Error::Reqwest(error) =\u003e {","lineNumber":199,"offsetAndLengths":[[31,2]]}]},{"__typename":"FileMatch","repository":{"name":"github.com/astral-sh/uv"},"file":{"path":"crates/uv-client/src/cached_client.rs","url":"/r/github.com/astral-sh/uv/-/blob/crates/uv-client/src/cached_client.rs","content":"use std::time::{Duration, Instant};\nuse std::{borrow::Cow, path::Path};\n\nuse futures::FutureExt;\nuse reqwest::{Request, Response};\nuse rkyv::util::AlignedVec;\nuse serde::de::DeserializeOwned;\nuse serde::{Deserialize, Serialize};\nuse tracing::{Instrument, debug, info_span, instrument, trace, warn};\n\nuse uv_cache::{CacheEntry, Freshness};\nuse uv_fs::write_atomic;\nuse uv_redacted::DisplaySafeUrl;\n\nuse crate::BaseClient;\nuse crate::base_client::RetryState;\nuse crate::error::ProblemDetails;\nuse crate::{\n Error, ErrorKind,\n httpcache::{AfterResponse, BeforeRequest, CachePolicy, CachePolicyBuilder},\n rkyvutil::OwnedArchive,\n};\n\n/// A trait the generalizes (de)serialization at a high level.\n///\n/// The main purpose of this trait is to make the `CachedClient` work for\n/// either serde or other mechanisms of serialization such as `rkyv`.\n///\n/// If you''re using Serde, then unless you want to control the format, callers\n/// should just use `CachedClient::get_serde`. This will use a default\n/// implementation of `Cacheable` internally.\n///\n/// Alternatively, callers using `rkyv` should use\n/// `CachedClient::get_cacheable`. If your types fit into the\n/// `rkyvutil::OwnedArchive` mold, then an implementation of `Cacheable` is\n/// already provided for that type.\npub trait Cacheable: Sized {\n /// This associated type permits customizing what the \"output\" type of\n /// deserialization is. It can be identical to `Self`.\n ///\n /// Typical use of this is for wrapper types used to provide blanket trait\n /// impls without hitting overlapping impl problems.\n type Target: Send + ''static;\n\n /// Deserialize a value from bytes aligned to a 16-byte boundary.\n fn from_aligned_bytes(bytes: AlignedVec) -\u003e Result\u003cSelf::Target, Error\u003e;\n /// Serialize bytes to a possibly owned byte buffer.\n fn to_bytes(\u0026self) -\u003e Result\u003cCow\u003c''_, [u8]\u003e, Error\u003e;\n /// Convert this type into its final form.\n fn into_target(self) -\u003e Self::Target;\n}\n\n/// A wrapper type that makes anything with Serde support automatically\n/// implement `Cacheable`.\n#[derive(Debug, Deserialize, Serialize)]\n#[serde(transparent)]\npub(crate) struct SerdeCacheable\u003cT\u003e {\n inner: T,\n}\n\nimpl\u003cT: Serialize + DeserializeOwned + Send + ''static\u003e Cacheable for SerdeCacheable\u003cT\u003e {\n type Target = T;\n\n fn from_aligned_bytes(bytes: AlignedVec) -\u003e Result\u003cT, Error\u003e {\n Ok(rmp_serde::from_slice::\u003cT\u003e(\u0026bytes).map_err(ErrorKind::Decode)?)\n }\n\n fn to_bytes(\u0026self) -\u003e Result\u003cCow\u003c''_, [u8]\u003e, Error\u003e {\n Ok(Cow::from(\n rmp_serde::to_vec(\u0026self.inner).map_err(ErrorKind::Encode)?,\n ))\n }\n\n fn into_target(self) -\u003e Self::Target {\n self.inner\n }\n}\n\n/// All `OwnedArchive` values are cacheable.\nimpl\u003cA\u003e Cacheable for OwnedArchive\u003cA\u003e\nwhere\n A: rkyv::Archive + for\u003c''a\u003e rkyv::Serialize\u003ccrate::rkyvutil::Serializer\u003c''a\u003e\u003e + Send + ''static,\n A::Archived: rkyv::Portable\n + rkyv::Deserialize\u003cA, crate::rkyvutil::Deserializer\u003e\n + for\u003c''a\u003e rkyv::bytecheck::CheckBytes\u003ccrate::rkyvutil::Validator\u003c''a\u003e\u003e,\n{\n type Target = Self;\n\n fn from_aligned_bytes(bytes: AlignedVec) -\u003e Result\u003cSelf, Error\u003e {\n Self::new(bytes)\n }\n\n fn to_bytes(\u0026self) -\u003e Result\u003cCow\u003c''_, [u8]\u003e, Error\u003e {\n Ok(Cow::from(Self::as_bytes(self)))\n }\n\n fn into_target(self) -\u003e Self::Target {\n self\n }\n}\n\n/// Dispatch type: Either a cached client error or a (user specified) error from the callback.\n#[derive(Debug)]\npub enum CachedClientError\u003cCallbackError: std::error::Error + ''static\u003e {\n /// The client tracks retries internally.\n Client(Error),\n /// Track retries before a callback explicitly, as we can''t attach them to the callback error\n /// type.\n Callback {\n retries: u32,\n err: CallbackError,\n duration: Duration,\n },\n}\n\nimpl\u003cCallbackError: std::error::Error + ''static\u003e CachedClientError\u003cCallbackError\u003e {\n /// Attach the combined number of retries to the error context, discarding the previous count.\n fn with_retries(self, retries: u32) -\u003e Self {\n match self {\n Self::Client(err) =\u003e Self::Client(err.with_retries(retries)),\n Self::Callback {\n retries: _,\n err,\n duration,\n } =\u003e Self::Callback {\n retries,\n err,\n duration,\n },\n }\n }\n\n fn retries(\u0026self) -\u003e u32 {\n match self {\n Self::Client(err) =\u003e err.retries(),\n Self::Callback { retries, .. } =\u003e *retries,\n }\n }\n\n fn error(\u0026self) -\u003e \u0026(dyn std::error::Error + ''static) {\n match self {\n Self::Client(err) =\u003e err,\n Self::Callback { err, .. } =\u003e err,\n }\n }\n}\n\nimpl\u003cCallbackError: std::error::Error + ''static\u003e From\u003cError\u003e for CachedClientError\u003cCallbackError\u003e {\n fn from(error: Error) -\u003e Self {\n Self::Client(error)\n }\n}\n\nimpl\u003cCallbackError: std::error::Error + ''static\u003e From\u003cErrorKind\u003e\n for CachedClientError\u003cCallbackError\u003e\n{\n fn from(error: ErrorKind) -\u003e Self {\n Self::Client(error.into())\n }\n}\n\nimpl\u003cE: Into\u003cSelf\u003e + std::error::Error + ''static\u003e From\u003cCachedClientError\u003cE\u003e\u003e for Error {\n /// Attach retry error context, if there were retries.\n fn from(error: CachedClientError\u003cE\u003e) -\u003e Self {\n match error {\n CachedClientError::Client(error) =\u003e error,\n CachedClientError::Callback {\n retries,\n err,\n duration,\n } =\u003e Self::new(err.into().into_kind(), retries, duration),\n }\n }\n}\n\n#[derive(Debug, Clone, Copy)]\npub enum CacheControl\u003c''a\u003e {\n /// Respect the `cache-control` header from the response.\n None,\n /// Apply `max-age=0, must-revalidate` to the request.\n MustRevalidate,\n /// Allow the client to return stale responses.\n AllowStale,\n /// Override the cache control header with a custom value.\n Override(\u0026''a str),\n}\n\nimpl From\u003cFreshness\u003e for CacheControl\u003c''_\u003e {\n fn from(value: Freshness) -\u003e Self {\n match value {\n Freshness::Fresh =\u003e Self::None,\n Freshness::Stale =\u003e Self::MustRevalidate,\n Freshness::Missing =\u003e Self::None,\n }\n }\n}\n\n/// Custom caching layer over [`reqwest::Client`].\n///\n/// The implementation takes inspiration from the `http-cache` crate, but adds support for running\n/// an async callback on the response before caching. We use this to e.g. store a\n/// parsed version of the wheel metadata and for our remote zip reader. In the latter case, we want\n/// to read a single file from a remote zip using range requests (so we don''t have to download the\n/// entire file). We send a HEAD request in the caching layer to check if the remote file has\n/// changed (and if range requests are supported), and in the callback we make the actual range\n/// requests if required.\n///\n/// Unlike `http-cache`, all outputs must be serializable/deserializable in some way, by\n/// implementing the `Cacheable` trait.\n///\n/// Again unlike `http-cache`, the caller gets full control over the cache key with the assumption\n/// that it''s a file.\n#[derive(Debug, Clone)]\npub struct CachedClient(BaseClient);\n\nimpl CachedClient {\n pub fn new(client: BaseClient) -\u003e Self {\n Self(client)\n }\n\n /// The underlying [`BaseClient`] without caching.\n pub fn uncached(\u0026self) -\u003e \u0026BaseClient {\n \u0026self.0\n }\n\n /// Make a cached request with a custom response transformation\n /// while using serde to (de)serialize cached responses.\n ///\n /// If a new response was received (no prior cached response or modified\n /// on the remote), the response is passed through `response_callback` and\n /// only the result is cached and returned. The `response_callback` is\n /// allowed to make subsequent requests, e.g. through the uncached client.\n #[instrument(skip_all)]\n pub async fn get_serde\u003c\n Payload: Serialize + DeserializeOwned + Send + ''static,\n CallBackError: std::error::Error + ''static,\n Callback: AsyncFn(Response) -\u003e Result\u003cPayload, CallBackError\u003e,\n \u003e(\n \u0026self,\n req: Request,\n cache_entry: \u0026CacheEntry,\n cache_control: CacheControl\u003c''_\u003e,\n response_callback: Callback,\n ) -\u003e Result\u003cPayload, CachedClientError\u003cCallBackError\u003e\u003e {\n let payload = self\n .get_cacheable(req, cache_entry, cache_control, async |resp| {\n let payload = response_callback(resp).await?;\n Ok(SerdeCacheable { inner: payload })\n })\n .await?;\n Ok(payload)\n }\n\n /// Make a cached request with a custom response transformation while using\n /// the `Cacheable` trait to (de)serialize cached responses.\n ///\n /// The purpose of this routine is the use of `Cacheable`. Namely, it\n /// generalizes over (de)serialization such that mechanisms other than\n /// serde (such as rkyv) can be used to manage (de)serialization of cached\n /// data.\n ///\n /// If a new response was received (no prior cached response or modified\n /// on the remote), the response is passed through `response_callback` and\n /// only the result is cached and returned. The `response_callback` is\n /// allowed to make subsequent requests, e.g. through the uncached client.\n #[instrument(skip_all)]\n pub async fn get_cacheable\u003c\n Payload: Cacheable,\n CallBackError: std::error::Error + ''static,\n Callback: AsyncFn(Response) -\u003e Result\u003cPayload, CallBackError\u003e,\n \u003e(\n \u0026self,\n req: Request,\n cache_entry: \u0026CacheEntry,\n cache_control: CacheControl\u003c''_\u003e,\n response_callback: Callback,\n ) -\u003e Result\u003cPayload::Target, CachedClientError\u003cCallBackError\u003e\u003e {\n let fresh_req = req.try_clone().expect(\"HTTP request must be cloneable\");\n let start = Instant::now();\n let cached_response = if let Some(cached) = Self::read_cache(cache_entry).await {\n self.send_cached(req, cache_control, cached)\n .boxed_local()\n .await?\n } else {\n debug!(\"No cache entry for: {}\", req.url());\n let (response, cache_policy) = self.fresh_request(req, cache_control).await?;\n CachedResponse::ModifiedOrNew {\n response,\n cache_policy,\n }\n };\n match cached_response {\n CachedResponse::FreshCache(cached) =\u003e match Payload::from_aligned_bytes(cached.data) {\n Ok(payload) =\u003e Ok(payload),\n Err(err) =\u003e {\n warn!(\n \"Broken fresh cache entry (for payload) at {}, removing: {err}\",\n cache_entry.path().display()\n );\n self.resend_and_heal_cache(\n fresh_req,\n cache_entry,\n cache_control,\n response_callback,\n )\n .await\n }\n },\n CachedResponse::NotModified { cached, new_policy } =\u003e {\n let refresh_cache =\n info_span!(\"refresh_cache\", file = %cache_entry.path().display());\n async {\n let data_with_cache_policy_bytes =\n DataWithCachePolicy::serialize(\u0026new_policy, \u0026cached.data)?;\n write_atomic(cache_entry.path(), data_with_cache_policy_bytes)\n .await\n .map_err(ErrorKind::CacheWrite)?;\n match Payload::from_aligned_bytes(cached.data) {\n Ok(payload) =\u003e Ok(payload),\n Err(err) =\u003e {\n warn!(\n \"Broken fresh cache entry after revalidation \\\n (for payload) at {}, removing: {err}\",\n cache_entry.path().display()\n );\n self.resend_and_heal_cache(\n fresh_req,\n cache_entry,\n cache_control,\n response_callback,\n )\n .await\n }\n }\n }\n .instrument(refresh_cache)\n .await\n }\n CachedResponse::ModifiedOrNew {\n response,\n cache_policy,\n } =\u003e {\n // If we got a modified response, but it''s a 304, then a validator failed (e.g., the\n // ETag didn''t match). We need to make a fresh request.\n if response.status() == http::StatusCode::NOT_MODIFIED {\n warn!(\"Server returned unusable 304 for: {}\", fresh_req.url());\n self.resend_and_heal_cache(\n fresh_req,\n cache_entry,\n cache_control,\n response_callback,\n )\n .await\n } else {\n self.run_response_callback(\n cache_entry,\n cache_policy,\n start,\n response,\n response_callback,\n )\n .await\n }\n }\n }\n }\n\n /// Make a request without checking whether the cache is fresh.\n pub async fn skip_cache\u003c\n Payload: Serialize + DeserializeOwned + Send + ''static,\n CallBackError: std::error::Error + ''static,\n Callback: AsyncFnOnce(Response) -\u003e Result\u003cPayload, CallBackError\u003e,\n \u003e(\n \u0026self,\n req: Request,\n cache_entry: \u0026CacheEntry,\n cache_control: CacheControl\u003c''_\u003e,\n response_callback: Callback,\n ) -\u003e Result\u003cPayload, CachedClientError\u003cCallBackError\u003e\u003e {\n let start = Instant::now();\n let (response, cache_policy) = self.fresh_request(req, cache_control).await?;\n\n let payload = self\n .run_response_callback(cache_entry, cache_policy, start, response, async |resp| {\n let payload = response_callback(resp).await?;\n Ok(SerdeCacheable { inner: payload })\n })\n .await?;\n\n Ok(payload)\n }\n\n async fn resend_and_heal_cache\u003c\n Payload: Cacheable,\n CallBackError: std::error::Error + ''static,\n Callback: AsyncFnOnce(Response) -\u003e Result\u003cPayload, CallBackError\u003e,\n \u003e(\n \u0026self,\n req: Request,\n cache_entry: \u0026CacheEntry,\n cache_control: CacheControl\u003c''_\u003e,\n response_callback: Callback,\n ) -\u003e Result\u003cPayload::Target, CachedClientError\u003cCallBackError\u003e\u003e {\n let _ = fs_err::tokio::remove_file(\u0026cache_entry.path()).await;\n let start = Instant::now();\n let (response, cache_policy) = self.fresh_request(req, cache_control).await?;\n self.run_response_callback(\n cache_entry,\n cache_policy,\n start,\n response,\n response_callback,\n )\n .await\n }\n\n async fn run_response_callback\u003c\n Payload: Cacheable,\n CallBackError: std::error::Error + ''static,\n Callback: AsyncFnOnce(Response) -\u003e Result\u003cPayload, CallBackError\u003e,\n \u003e(\n \u0026self,\n cache_entry: \u0026CacheEntry,\n cache_policy: Option\u003cBox\u003cCachePolicy\u003e\u003e,\n start: Instant,\n response: Response,\n response_callback: Callback,\n ) -\u003e Result\u003cPayload::Target, CachedClientError\u003cCallBackError\u003e\u003e {\n let new_cache = info_span!(\"new_cache\", file = %cache_entry.path().display());\n // Capture retries from the retry middleware\n let retries = response\n .extensions()\n .get::\u003creqwest_retry::RetryCount\u003e()\n .map(|retries| retries.value())\n .unwrap_or_default();\n let data = response_callback(response)\n .boxed_local()\n .await\n .map_err(|err| CachedClientError::Callback {\n retries,\n err,\n duration: start.elapsed(),\n })?;\n let Some(cache_policy) = cache_policy else {\n return Ok(data.into_target());\n };\n async {\n fs_err::tokio::create_dir_all(cache_entry.dir())\n .await\n .map_err(ErrorKind::CacheWrite)?;\n let data_with_cache_policy_bytes =\n DataWithCachePolicy::serialize(\u0026cache_policy, \u0026data.to_bytes()?)?;\n write_atomic(cache_entry.path(), data_with_cache_policy_bytes)\n .await\n .map_err(ErrorKind::CacheWrite)?;\n Ok(data.into_target())\n }\n .instrument(new_cache)\n .await\n }\n\n #[instrument(name = \"read_and_parse_cache\", skip_all, fields(file = %cache_entry.path().display()\n ))]\n async fn read_cache(cache_entry: \u0026CacheEntry) -\u003e Option\u003cDataWithCachePolicy\u003e {\n match DataWithCachePolicy::from_path_async(cache_entry.path()).await {\n Ok(data) =\u003e Some(data),\n Err(err) =\u003e {\n // When we know the cache entry doesn''t exist, then things are\n // normal and we shouldn''t emit a WARN.\n if err.is_file_not_exists() {\n trace!(\"No cache entry exists for {}\", cache_entry.path().display());\n } else {\n warn!(\n \"Broken cache policy entry at {}, removing: {err}\",\n cache_entry.path().display()\n );\n let _ = fs_err::tokio::remove_file(\u0026cache_entry.path()).await;\n }\n None\n }\n }\n }\n\n /// Send a request given that we have a (possibly) stale cached response.\n ///\n /// If the cached response is valid but stale, then this will attempt a\n /// revalidation request.\n async fn send_cached(\n \u0026self,\n mut req: Request,\n cache_control: CacheControl\u003c''_\u003e,\n cached: DataWithCachePolicy,\n ) -\u003e Result\u003cCachedResponse, Error\u003e {\n // Apply the cache control header, if necessary.\n match cache_control {\n CacheControl::None | CacheControl::AllowStale | CacheControl::Override(..) =\u003e {}\n CacheControl::MustRevalidate =\u003e {\n req.headers_mut().insert(\n http::header::CACHE_CONTROL,\n http::HeaderValue::from_static(\"no-cache\"),\n );\n }\n }\n Ok(match cached.cache_policy.before_request(\u0026mut req) {\n BeforeRequest::Fresh =\u003e {\n debug!(\"Found fresh response for: {}\", req.url());\n CachedResponse::FreshCache(cached)\n }\n BeforeRequest::Stale(new_cache_policy_builder) =\u003e match cache_control {\n CacheControl::None | CacheControl::MustRevalidate | CacheControl::Override(_) =\u003e {\n debug!(\"Found stale response for: {}\", req.url());\n self.send_cached_handle_stale(\n req,\n cache_control,\n cached,\n new_cache_policy_builder,\n )\n .await?\n }\n CacheControl::AllowStale =\u003e {\n debug!(\"Found stale (but allowed) response for: {}\", req.url());\n CachedResponse::FreshCache(cached)\n }\n },\n BeforeRequest::NoMatch =\u003e {\n // This shouldn''t happen; if it does, we''ll override the cache.\n warn!(\n \"Cached response doesn''t match current request for: {}\",\n req.url()\n );\n let (response, cache_policy) = self.fresh_request(req, cache_control).await?;\n CachedResponse::ModifiedOrNew {\n response,\n cache_policy,\n }\n }\n })\n }\n\n async fn send_cached_handle_stale(\n \u0026self,\n req: Request,\n cache_control: CacheControl\u003c''_\u003e,\n cached: DataWithCachePolicy,\n new_cache_policy_builder: CachePolicyBuilder,\n ) -\u003e Result\u003cCachedResponse, Error\u003e {\n let url = DisplaySafeUrl::from_url(req.url().clone());\n debug!(\"Sending revalidation request for: {url}\");\n let start = Instant::now();\n let mut response = self\n .0\n .execute(req)\n .instrument(info_span!(\"revalidation_request\", url = url.as_str()))\n .await\n .map_err(|err| Error::from_reqwest_middleware(url.clone(), err, start))?;\n trace!(\n \"Received response for revalidation request with status {} for: {}\",\n response.status(),\n url\n );\n\n // Check for HTTP error status and extract problem details if available\n if let Err(status_error) = response.error_for_status_ref() {\n let problem_details = ProblemDetails::try_from_response(response).await;\n return Err(ErrorKind::from_reqwest_with_problem_details(\n url.clone(),\n status_error,\n problem_details,\n )\n .into());\n }\n\n // If the user set a custom `Cache-Control` header, override it.\n if let CacheControl::Override(header) = cache_control {\n response.headers_mut().insert(\n http::header::CACHE_CONTROL,\n http::HeaderValue::from_str(header)\n .expect(\"Cache-Control header must be valid UTF-8\"),\n );\n }\n\n match cached\n .cache_policy\n .after_response(new_cache_policy_builder, \u0026response)\n {\n AfterResponse::NotModified(new_policy) =\u003e {\n debug!(\"Found not-modified response for: {url}\");\n Ok(CachedResponse::NotModified {\n cached,\n new_policy: Box::new(new_policy),\n })\n }\n AfterResponse::Modified(new_policy) =\u003e {\n debug!(\"Found modified response for: {url}\");\n Ok(CachedResponse::ModifiedOrNew {\n response,\n cache_policy: new_policy\n .to_archived()\n .is_storable()\n .then(|| Box::new(new_policy)),\n })\n }\n }\n }\n\n #[instrument(skip_all, fields(url = req.url().as_str()))]\n async fn fresh_request(\n \u0026self,\n req: Request,\n cache_control: CacheControl\u003c''_\u003e,\n ) -\u003e Result\u003c(Response, Option\u003cBox\u003cCachePolicy\u003e\u003e), Error\u003e {\n let url = DisplaySafeUrl::from_url(req.url().clone());\n debug!(\"Sending fresh {} request for: {}\", req.method(), url);\n let cache_policy_builder = CachePolicyBuilder::new(\u0026req);\n let start = Instant::now();\n let mut response = self\n .0\n .execute(req)\n .await\n .map_err(|err| Error::from_reqwest_middleware(url.clone(), err, start))?;\n trace!(\n \"Received response for fresh request with status {} for: {}\",\n response.status(),\n url\n );\n\n // If the user set a custom `Cache-Control` header, override it.\n if let CacheControl::Override(header) = cache_control {\n response.headers_mut().insert(\n http::header::CACHE_CONTROL,\n http::HeaderValue::from_str(header)\n .expect(\"Cache-Control header must be valid UTF-8\"),\n );\n }\n\n let retry_count = response\n .extensions()\n .get::\u003creqwest_retry::RetryCount\u003e()\n .map(|retries| retries.value());\n\n if let Err(status_error) = response.error_for_status_ref() {\n let problem_details = ProblemDetails::try_from_response(response).await;\n return Err(Error::new(\n ErrorKind::from_reqwest_with_problem_details(url, status_error, problem_details),\n retry_count.unwrap_or_default(),\n start.elapsed(),\n ));\n }\n\n let cache_policy = cache_policy_builder.build(\u0026response);\n let cache_policy = if cache_policy.to_archived().is_storable() {\n Some(Box::new(cache_policy))\n } else {\n None\n };\n Ok((response, cache_policy))\n }\n\n /// Perform a [`CachedClient::get_serde`] request with a default retry strategy.\n #[instrument(skip_all)]\n pub async fn get_serde_with_retry\u003c\n Payload: Serialize + DeserializeOwned + Send + ''static,\n CallBackError: std::error::Error + ''static,\n Callback: AsyncFn(Response) -\u003e Result\u003cPayload, CallBackError\u003e,\n \u003e(\n \u0026self,\n req: Request,\n cache_entry: \u0026CacheEntry,\n cache_control: CacheControl\u003c''_\u003e,\n response_callback: Callback,\n ) -\u003e Result\u003cPayload, CachedClientError\u003cCallBackError\u003e\u003e {\n let payload = self\n .get_cacheable_with_retry(req, cache_entry, cache_control, async |resp| {\n let payload = response_callback(resp).await?;\n Ok(SerdeCacheable { inner: payload })\n })\n .await?;\n Ok(payload)\n }\n\n /// Perform a [`CachedClient::get_cacheable`] request with a default retry strategy.\n ///\n /// See: \u003chttps://github.com/TrueLayer/reqwest-middleware/blob/8a494c165734e24c62823714843e1c9347027e8a/reqwest-retry/src/middleware.rs#L137\u003e\n #[instrument(skip_all)]\n pub async fn get_cacheable_with_retry\u003c\n Payload: Cacheable,\n CallBackError: std::error::Error + ''static,\n Callback: AsyncFn(Response) -\u003e Result\u003cPayload, CallBackError\u003e,\n \u003e(\n \u0026self,\n req: Request,\n cache_entry: \u0026CacheEntry,\n cache_control: CacheControl\u003c''_\u003e,\n response_callback: Callback,\n ) -\u003e Result\u003cPayload::Target, CachedClientError\u003cCallBackError\u003e\u003e {\n let mut retry_state = RetryState::start(self.uncached().retry_policy(), req.url().clone());\n loop {\n let fresh_req = req.try_clone().expect(\"HTTP request must be cloneable\");\n let result = self\n .get_cacheable(fresh_req, cache_entry, cache_control, \u0026response_callback)\n .await;\n\n match result {\n Ok(ok) =\u003e return Ok(ok),\n Err(err) =\u003e {\n if let Some(backoff) = retry_state.should_retry(err.error(), err.retries()) {\n retry_state.sleep_backoff(backoff).await;\n continue;\n }\n return Err(err.with_retries(retry_state.total_retries()));\n }\n }\n }\n }\n\n /// Perform a [`CachedClient::skip_cache`] request with a default retry strategy.\n ///\n /// See: \u003chttps://github.com/TrueLayer/reqwest-middleware/blob/8a494c165734e24c62823714843e1c9347027e8a/reqwest-retry/src/middleware.rs#L137\u003e\n pub async fn skip_cache_with_retry\u003c\n Payload: Serialize + DeserializeOwned + Send + ''static,\n CallBackError: std::error::Error + ''static,\n Callback: AsyncFn(Response) -\u003e Result\u003cPayload, CallBackError\u003e,\n \u003e(\n \u0026self,\n req: Request,\n cache_entry: \u0026CacheEntry,\n cache_control: CacheControl\u003c''_\u003e,\n response_callback: Callback,\n ) -\u003e Result\u003cPayload, CachedClientError\u003cCallBackError\u003e\u003e {\n let mut retry_state = RetryState::start(self.uncached().retry_policy(), req.url().clone());\n loop {\n let fresh_req = req.try_clone().expect(\"HTTP request must be cloneable\");\n let result = self\n .skip_cache(fresh_req, cache_entry, cache_control, \u0026response_callback)\n .await;\n\n match result {\n Ok(ok) =\u003e return Ok(ok),\n Err(err) =\u003e {\n if let Some(backoff) = retry_state.should_retry(err.error(), err.retries()) {\n retry_state.sleep_backoff(backoff).await;\n continue;\n }\n return Err(err.with_retries(retry_state.total_retries()));\n }\n }\n }\n }\n}\n\n#[derive(Debug)]\nenum CachedResponse {\n /// The cached response is fresh without an HTTP request (e.g. age \u003c max-age).\n FreshCache(DataWithCachePolicy),\n /// The cached response is fresh after an HTTP request (e.g. 304 not modified)\n NotModified {\n /// The cached response (with its old cache policy).\n cached: DataWithCachePolicy,\n /// The new [`CachePolicy`] is used to determine if the response\n /// is fresh or stale when making subsequent requests for the same\n /// resource. This policy should overwrite the old policy associated\n /// with the cached response. In particular, this new policy is derived\n /// from data received in a revalidation response, which might change\n /// the parameters of cache behavior.\n ///\n /// The policy is large (352 bytes at time of writing), so we reduce\n /// the stack size by boxing it.\n new_policy: Box\u003cCachePolicy\u003e,\n },\n /// There was no prior cached response or the cache was outdated\n ///\n /// The cache policy is `None` if it isn''t storable\n ModifiedOrNew {\n /// The response received from the server.\n response: Response,\n /// The [`CachePolicy`] is used to determine if the response is fresh or\n /// stale when making subsequent requests for the same resource.\n ///\n /// The policy is large (352 bytes at time of writing), so we reduce\n /// the stack size by boxing it.\n cache_policy: Option\u003cBox\u003cCachePolicy\u003e\u003e,\n },\n}\n\n/// Represents an arbitrary data blob with an associated HTTP cache policy.\n///\n/// The cache policy is used to determine whether the data blob is stale or\n/// not.\n///\n/// # Format\n///\n/// This type encapsulates the format for how blobs of data are stored on\n/// disk. The format is very simple. First, the blob of data is written as-is.\n/// Second, the archived representation of a `CachePolicy` is written. Thirdly,\n/// the length, in bytes, of the archived `CachePolicy` is written as a 64-bit\n/// little endian integer.\n///\n/// Reading the format is done via an `AlignedVec` so that `rkyv` can correctly\n/// read the archived representation of the data blob. The cache policy is\n/// split into its own `AlignedVec` allocation.\n///\n/// # Future ideas\n///\n/// This format was also chosen because it should in theory permit rewriting\n/// the cache policy without needing to rewrite the data blob if the blob has\n/// not changed. For example, this case occurs when a revalidation request\n/// responds with HTTP 304 NOT MODIFIED. At time of writing, this is not yet\n/// implemented because 1) the synchronization specifics of mutating a cache\n/// file have not been worked out and 2) it''s not clear if it''s a win.\n///\n/// An alternative format would be to write the cache policy and the\n/// blob in two distinct files. This would avoid needing to worry about\n/// synchronization, but it means reading two files instead of one for every\n/// cached response in the fast path. It''s unclear whether it''s worth it.\n/// (Experiments have not yet been done.)\n///\n/// Another approach here would be to memory map the file and rejigger\n/// `OwnedArchive` (or create a new type) that works with a memory map instead\n/// of an `AlignedVec`. This will require care to ensure alignment is handled\n/// correctly. This approach has not been litigated yet. I did not start with\n/// it because experiments with ripgrep have tended to show that (on Linux)\n/// memory mapping a bunch of small files ends up being quite a bit slower than\n/// just reading them on to the heap.\n#[derive(Debug)]\npub struct DataWithCachePolicy {\n pub data: AlignedVec,\n cache_policy: OwnedArchive\u003cCachePolicy\u003e,\n}\n\nimpl DataWithCachePolicy {\n /// Loads cached data and its associated HTTP cache policy from the given\n /// file path in an asynchronous fashion (via `spawn_blocking`).\n ///\n /// # Errors\n ///\n /// If the given byte buffer is not in a valid format or if reading the\n /// file given fails, then this returns an error.\n async fn from_path_async(path: \u0026Path) -\u003e Result\u003cSelf, Error\u003e {\n let path = path.to_path_buf();\n tokio::task::spawn_blocking(move || Self::from_path_sync(\u0026path))\n .await\n // This just forwards panics from the closure.\n .unwrap()\n }\n\n /// Loads cached data and its associated HTTP cache policy from the given\n /// file path in a synchronous fashion.\n ///\n /// # Errors\n ///\n /// If the given byte buffer is not in a valid format or if reading the\n /// file given fails, then this returns an error.\n #[instrument]\n fn from_path_sync(path: \u0026Path) -\u003e Result\u003cSelf, Error\u003e {\n let file = fs_err::File::open(path).map_err(ErrorKind::Io)?;\n // Note that we don''t wrap our file in a buffer because it will just\n // get passed to AlignedVec::extend_from_reader, which doesn''t benefit\n // from an intermediary buffer. In effect, the AlignedVec acts as the\n // buffer.\n Self::from_reader(file)\n }\n\n /// Loads cached data and its associated HTTP cache policy from the given\n /// reader.\n ///\n /// # Errors\n ///\n /// If the given byte buffer is not in a valid format or if the reader\n /// fails, then this returns an error.\n pub fn from_reader(mut rdr: impl std::io::Read) -\u003e Result\u003cSelf, Error\u003e {\n let mut aligned_bytes = AlignedVec::new();\n aligned_bytes\n .extend_from_reader(\u0026mut rdr)\n .map_err(ErrorKind::Io)?;\n Self::from_aligned_bytes(aligned_bytes)\n }\n\n /// Loads cached data and its associated HTTP cache policy form an in\n /// memory byte buffer.\n ///\n /// # Errors\n ///\n /// If the given byte buffer is not in a valid format, then this\n /// returns an error.\n fn from_aligned_bytes(mut bytes: AlignedVec) -\u003e Result\u003cSelf, Error\u003e {\n let cache_policy = Self::deserialize_cache_policy(\u0026mut bytes)?;\n Ok(Self {\n data: bytes,\n cache_policy,\n })\n }\n\n /// Serializes the given cache policy and arbitrary data blob to an in\n /// memory byte buffer.\n ///\n /// # Errors\n ///\n /// If there was a problem converting the given cache policy to its\n /// serialized representation, then this routine will return an error.\n fn serialize(cache_policy: \u0026CachePolicy, data: \u0026[u8]) -\u003e Result\u003cVec\u003cu8\u003e, Error\u003e {\n let mut buf = vec![];\n Self::serialize_to_writer(cache_policy, data, \u0026mut buf)?;\n Ok(buf)\n }\n\n /// Serializes the given cache policy and arbitrary data blob to the given\n /// writer.\n ///\n /// # Errors\n ///\n /// If there was a problem converting the given cache policy to its\n /// serialized representation or if the writer returns an error, then\n /// this routine will return an error.\n fn serialize_to_writer(\n cache_policy: \u0026CachePolicy,\n data: \u0026[u8],\n mut wtr: impl std::io::Write,\n ) -\u003e Result\u003c(), Error\u003e {\n let cache_policy_archived = OwnedArchive::from_unarchived(cache_policy)?;\n let cache_policy_bytes = OwnedArchive::as_bytes(\u0026cache_policy_archived);\n wtr.write_all(data).map_err(ErrorKind::Io)?;\n wtr.write_all(cache_policy_bytes).map_err(ErrorKind::Io)?;\n let len = u64::try_from(cache_policy_bytes.len()).map_err(|_| {\n let msg = format!(\n \"failed to represent {} (length of cache policy) in a u64\",\n cache_policy_bytes.len()\n );\n ErrorKind::Io(std::io::Error::other(msg))\n })?;\n wtr.write_all(\u0026len.to_le_bytes()).map_err(ErrorKind::Io)?;\n Ok(())\n }\n\n /// Deserializes a `OwnedArchive\u003cCachePolicy\u003e` off the end of the given\n /// aligned bytes. Upon success, the given bytes will only contain the\n /// data itself. The bytes representing the cached policy will have been\n /// removed.\n ///\n /// # Errors\n ///\n /// This returns an error if the cache policy could not be deserialized\n /// from the end of the given bytes.\n fn deserialize_cache_policy(\n bytes: \u0026mut AlignedVec,\n ) -\u003e Result\u003cOwnedArchive\u003cCachePolicy\u003e, Error\u003e {\n let len = Self::deserialize_cache_policy_len(bytes)?;\n let cache_policy_bytes_start = bytes.len() - (len + 8);\n let cache_policy_bytes = \u0026bytes[cache_policy_bytes_start..][..len];\n let mut cache_policy_bytes_aligned = AlignedVec::with_capacity(len);\n cache_policy_bytes_aligned.extend_from_slice(cache_policy_bytes);\n assert!(\n cache_policy_bytes_start \u003c= bytes.len(),\n \"slicing cache policy should result in a truncation\"\n );\n // Technically this will keep the extra capacity used to store the\n // cache policy around. But it should be pretty small, and it saves a\n // realloc. (It''s unclear whether that matters more or less than the\n // extra memory usage.)\n bytes.resize(cache_policy_bytes_start, 0);\n OwnedArchive::new(cache_policy_bytes_aligned)\n }\n\n /// Deserializes the length, in bytes, of the cache policy given a complete\n /// serialized byte buffer of a `DataWithCachePolicy`.\n ///\n /// Upon success, callers are guaranteed that\n /// `\u0026bytes[bytes.len() - (len + 8)..][..len]` will not panic.\n ///\n /// # Errors\n ///\n /// This returns an error if the length could not be read as a `usize` or is\n /// otherwise known to be invalid. (For example, it is a length that is bigger\n /// than `bytes.len()`.)\n fn deserialize_cache_policy_len(bytes: \u0026[u8]) -\u003e Result\u003cusize, Error\u003e {\n let Some(cache_policy_len_start) = bytes.len().checked_sub(8) else {\n let msg = format!(\n \"data-with-cache-policy buffer should be at least 8 bytes \\\n in length, but is {} bytes\",\n bytes.len(),\n );\n return Err(ErrorKind::ArchiveRead(msg).into());\n };\n let cache_policy_len_bytes = \u003c[u8; 8]\u003e::try_from(\u0026bytes[cache_policy_len_start..])\n .expect(\"cache policy length is 8 bytes\");\n let len_u64 = u64::from_le_bytes(cache_policy_len_bytes);\n let Ok(len_usize) = usize::try_from(len_u64) else {\n let msg = format!(\n \"data-with-cache-policy has cache policy length of {len_u64}, \\\n but overflows usize\",\n );\n return Err(ErrorKind::ArchiveRead(msg).into());\n };\n if bytes.len() \u003c len_usize + 8 {\n let msg = format!(\n \"invalid cache entry: data-with-cache-policy has cache policy length of {}, \\\n but total buffer size is {}\",\n len_usize,\n bytes.len(),\n );\n return Err(ErrorKind::ArchiveRead(msg).into());\n }\n Ok(len_usize)\n }\n}\n"},"lineMatches":[{"preview":"impl\u003cE: Into\u003cSelf\u003e + std::error::Error + ''static\u003e From\u003cCachedClientError\u003cE\u003e\u003e for Error {","lineNumber":161,"offsetAndLengths":[[25,2],[32,2]]},{"preview":" rmp_serde::to_vec(\u0026self.inner).map_err(ErrorKind::Encode)?,","lineNumber":69,"offsetAndLengths":[[61,2]]},{"preview":"pub enum CachedClientError\u003cCallbackError: std::error::Error + ''static\u003e {","lineNumber":103,"offsetAndLengths":[[46,2],[53,2]]},{"preview":"impl\u003cCallbackError: std::error::Error + ''static\u003e CachedClientError\u003cCallbackError\u003e {","lineNumber":115,"offsetAndLengths":[[24,2],[31,2]]},{"preview":" fn error(\u0026self) -\u003e \u0026(dyn std::error::Error + ''static) {","lineNumber":139,"offsetAndLengths":[[33,2],[40,2]]},{"preview":"impl\u003cCallbackError: std::error::Error + ''static\u003e From\u003cError\u003e for CachedClientError\u003cCallbackError\u003e {","lineNumber":147,"offsetAndLengths":[[24,2]]}]}]}}}}'
254 headers:
255 Content-Type:
256 - application/json
257 status: 200 OK
258 code: 200
259 duration: 37.843117542s
260- id: 7
261 request:
262 proto: HTTP/1.1
263 proto_major: 1
264 proto_minor: 1
265 content_length: 83697
266 host: ""
267 body: "{\"messages\":[{\"content\":\"You are Crush, a powerful AI Assistant that runs in the CLI.\\n\\n<critical_rules>\\nThese rules override everything else. Follow them strictly:\\n\\n1. **READ BEFORE EDITING**: Never edit a file you haven't already read in this conversation. Once read, you don't need to re-read unless it changed. Pay close attention to exact formatting, indentation, and whitespace - these must match exactly in your edits.\\n2. **BE AUTONOMOUS**: Don't ask questions - search, read, think, decide, act. Break complex tasks into steps and complete them all. Systematically try alternative strategies (different commands, search terms, tools, refactors, or scopes) until either the task is complete or you hit a hard external limit (missing credentials, permissions, files, or network access you cannot change). Only stop for actual blocking errors, not perceived difficulty.\\n3. **TEST AFTER CHANGES**: Run tests immediately after each modification.\\n4. **BE CONCISE**: Keep output concise (default <4 lines), unless explaining complex changes or asked for detail. Conciseness applies to output only, not to thoroughness of work.\\n5. **USE EXACT MATCHES**: When editing, match text exactly including whitespace, indentation, and line breaks.\\n6. **NEVER COMMIT**: Unless user explicitly says \\\"commit\\\".\\n7. **FOLLOW MEMORY FILE INSTRUCTIONS**: If memory files contain specific instructions, preferences, or commands, you MUST follow them.\\n8. **NEVER ADD COMMENTS**: Only add comments if the user asked you to do so. Focus on *why* not *what*. NEVER communicate with the user through code comments.\\n9. **SECURITY FIRST**: Only assist with defensive security tasks. Refuse to create, modify, or improve code that may be used maliciously.\\n10. **NO URL GUESSING**: Only use URLs provided by the user or found in local files.\\n11. **NEVER PUSH TO REMOTE**: Don't push changes to remote repositories unless explicitly asked.\\n12. **DON'T REVERT CHANGES**: Don't revert changes unless they caused errors or the user explicitly asks.\\n13. **TOOL CONSTRAINTS**: Only use documented tools. Never attempt 'apply_patch' or 'apply_diff' - they don't exist. Use 'edit' or 'multiedit' instead.\\n</critical_rules>\\n\\n<communication_style>\\nKeep responses minimal:\\n- Under 4 lines of text (tool use doesn't count)\\n- Conciseness is about **text only**: always fully implement the requested feature, tests, and wiring even if that requires many tool calls.\\n- No preamble (\\\"Here's...\\\", \\\"I'll...\\\")\\n- No postamble (\\\"Let me know...\\\", \\\"Hope this helps...\\\")\\n- One-word answers when possible\\n- No emojis ever\\n- No explanations unless user asks\\n- Never send acknowledgement-only responses; after receiving new context or instructions, immediately continue the task or state the concrete next action you will take.\\n- Use rich Markdown formatting (headings, bullet lists, tables, code fences) for any multi-sentence or explanatory answer; only use plain unformatted text if the user explicitly asks.\\n- Respond ALL sentenses in the same spoken language the prompt was written in.\\n\\nExamples:\\nuser: what is 2+2?\\nassistant: 4\\n\\nuser: list files in src/\\nassistant: [uses ls tool]\\nfoo.c, bar.c, baz.c\\n\\nuser: which file has the foo implementation?\\nassistant: src/foo.c\\n\\nuser: add error handling to the login function\\nassistant: [searches for login, reads file, edits with exact match, runs tests]\\nDone\\n\\nuser: Where are errors from the client handled?\\nassistant: Clients are marked as failed in the `connectToServer` function in src/services/process.go:712.\\n</communication_style>\\n\\n<code_references>\\nWhen referencing specific functions or code locations, use the pattern `file_path:line_number` to help users navigate:\\n- Example: \\\"The error is handled in src/main.go:45\\\"\\n- Example: \\\"See the implementation in pkg/utils/helper.go:123-145\\\"\\n</code_references>\\n\\n<workflow>\\nFor every task, follow this sequence internally (don't narrate it):\\n\\n**Before acting**:\\n- Search codebase for relevant files\\n- Read files to understand current state\\n- Check memory for stored commands\\n- Identify what needs to change\\n- Use `git log` and `git blame` for additional context when needed\\n\\n**While acting**:\\n- Read entire file before editing it\\n- Before editing: verify exact whitespace and indentation from View output\\n- Use exact text for find/replace (include whitespace)\\n- Make one logical change at a time\\n- After each change: run tests\\n- If tests fail: fix immediately\\n- If edit fails: read more context, don't guess - the text must match exactly\\n- Keep going until query is completely resolved before yielding to user\\n- For longer tasks, send brief progress updates (under 10 words) BUT IMMEDIATELY CONTINUE WORKING - progress updates are not stopping points\\n\\n**Before finishing**:\\n- Verify ENTIRE query is resolved (not just first step)\\n- All described next steps must be completed\\n- Cross-check the original prompt and your own mental checklist; if any feasible part remains undone, continue working instead of responding.\\n- Run lint/typecheck if in memory\\n- Verify all changes work\\n- Keep response under 4 lines\\n\\n**Key behaviors**:\\n- Use find_references before changing shared code\\n- Follow existing patterns (check similar files)\\n- If stuck, try different approach (don't repeat failures)\\n- Make decisions yourself (search first, don't ask)\\n- Fix problems at root cause, not surface-level patches\\n- Don't fix unrelated bugs or broken tests (mention them in final message if relevant)\\n</workflow>\\n\\n<decision_making>\\n**Make decisions autonomously** - don't ask when you can:\\n- Search to find the answer\\n- Read files to see patterns\\n- Check similar code\\n- Infer from context\\n- Try most likely approach\\n- When requirements are underspecified but not obviously dangerous, make the most reasonable assumptions based on project patterns and memory files, briefly state them if needed, and proceed instead of waiting for clarification.\\n\\n**Only stop/ask user if**:\\n- Truly ambiguous business requirement\\n- Multiple valid approaches with big tradeoffs\\n- Could cause data loss\\n- Exhausted all attempts and hit actual blocking errors\\n\\n**When requesting information/access**:\\n- Exhaust all available tools, searches, and reasonable assumptions first.\\n- Never say \\\"Need more info\\\" without detail.\\n- In the same message, list each missing item, why it is required, acceptable substitutes, and what you already attempted.\\n- State exactly what you will do once the information arrives so the user knows the next step.\\n\\nWhen you must stop, first finish all unblocked parts of the request, then clearly report: (a) what you tried, (b) exactly why you are blocked, and (c) the minimal external action required. Don't stop just because one path failed—exhaust multiple plausible approaches first.\\n\\n**Never stop for**:\\n- Task seems too large (break it down)\\n- Multiple files to change (change them)\\n- Concerns about \\\"session limits\\\" (no such limits exist)\\n- Work will take many steps (do all the steps)\\n\\nExamples of autonomous decisions:\\n- File location → search for similar files\\n- Test command → check package.json/memory\\n- Code style → read existing code\\n- Library choice → check what's used\\n- Naming → follow existing names\\n</decision_making>\\n\\n<editing_files>\\n**Available edit tools:**\\n- `edit` - Single find/replace in a file\\n- `multiedit` - Multiple find/replace operations in one file\\n- `write` - Create/overwrite entire file\\n\\nNever use `apply_patch` or similar - those tools don't exist.\\n\\nCritical: ALWAYS read files before editing them in this conversation.\\n\\nWhen using edit tools:\\n1. Read the file first - note the EXACT indentation (spaces vs tabs, count)\\n2. Copy the exact text including ALL whitespace, newlines, and indentation\\n3. Include 3-5 lines of context before and after the target\\n4. Verify your old_string would appear exactly once in the file\\n5. If uncertain about whitespace, include more surrounding context\\n6. Verify edit succeeded\\n7. Run tests\\n\\n**Whitespace matters**:\\n- Count spaces/tabs carefully (use View tool line numbers as reference)\\n- Include blank lines if they exist\\n- Match line endings exactly\\n- When in doubt, include MORE context rather than less\\n\\nEfficiency tips:\\n- Don't re-read files after successful edits (tool will fail if it didn't work)\\n- Same applies for making folders, deleting files, etc.\\n\\nCommon mistakes to avoid:\\n- Editing without reading first\\n- Approximate text matches\\n- Wrong indentation (spaces vs tabs, wrong count)\\n- Missing or extra blank lines\\n- Not enough context (text appears multiple times)\\n- Trimming whitespace that exists in the original\\n- Not testing after changes\\n</editing_files>\\n\\n<whitespace_and_exact_matching>\\nThe Edit tool is extremely literal. \\\"Close enough\\\" will fail.\\n\\n**Before every edit**:\\n1. View the file and locate the exact lines to change\\n2. Copy the text EXACTLY including:\\n - Every space and tab\\n - Every blank line\\n - Opening/closing braces position\\n - Comment formatting\\n3. Include enough surrounding lines (3-5) to make it unique\\n4. Double-check indentation level matches\\n\\n**Common failures**:\\n- `func foo() {` vs `func foo(){` (space before brace)\\n- Tab vs 4 spaces vs 2 spaces\\n- Missing blank line before/after\\n- `// comment` vs `//comment` (space after //)\\n- Different number of spaces in indentation\\n\\n**If edit fails**:\\n- View the file again at the specific location\\n- Copy even more context\\n- Check for tabs vs spaces\\n- Verify line endings\\n- Try including the entire function/block if needed\\n- Never retry with guessed changes - get the exact text first\\n</whitespace_and_exact_matching>\\n\\n<task_completion>\\nEnsure every task is implemented completely, not partially or sketched.\\n\\n1. **Think before acting** (for non-trivial tasks)\\n - Identify all components that need changes (models, logic, routes, config, tests, docs)\\n - Consider edge cases and error paths upfront\\n - Form a mental checklist of requirements before making the first edit\\n - This planning happens internally - don't narrate it to the user\\n\\n2. **Implement end-to-end**\\n - Treat every request as complete work: if adding a feature, wire it fully\\n - Update all affected files (callers, configs, tests, docs)\\n - Don't leave TODOs or \\\"you'll also need to...\\\" - do it yourself\\n - No task is too large - break it down and complete all parts\\n - For multi-part prompts, treat each bullet/question as a checklist item and ensure every item is implemented or answered. Partial completion is not an acceptable final state.\\n\\n3. **Verify before finishing**\\n - Re-read the original request and verify each requirement is met\\n - Check for missing error handling, edge cases, or unwired code\\n - Run tests to confirm the implementation works\\n - Only say \\\"Done\\\" when truly done - never stop mid-task\\n</task_completion>\\n\\n<error_handling>\\nWhen errors occur:\\n1. Read complete error message\\n2. Understand root cause (isolate with debug logs or minimal reproduction if needed)\\n3. Try different approach (don't repeat same action)\\n4. Search for similar code that works\\n5. Make targeted fix\\n6. Test to verify\\n7. For each error, attempt at least two or three distinct remediation strategies (search similar code, adjust commands, narrow or widen scope, change approach) before concluding the problem is externally blocked.\\n\\nCommon errors:\\n- Import/Module → check paths, spelling, what exists\\n- Syntax → check brackets, indentation, typos\\n- Tests fail → read test, see what it expects\\n- File not found → use ls, check exact path\\n\\n**Edit tool \\\"old_string not found\\\"**:\\n- View the file again at the target location\\n- Copy the EXACT text including all whitespace\\n- Include more surrounding context (full function if needed)\\n- Check for tabs vs spaces, extra/missing blank lines\\n- Count indentation spaces carefully\\n- Don't retry with approximate matches - get the exact text\\n</error_handling>\\n\\n<memory_instructions>\\nMemory files store commands, preferences, and codebase info. Update them when you discover:\\n- Build/test/lint commands\\n- Code style preferences\\n- Important codebase patterns\\n- Useful project information\\n</memory_instructions>\\n\\n<code_conventions>\\nBefore writing code:\\n1. Check if library exists (look at imports, package.json)\\n2. Read similar code for patterns\\n3. Match existing style\\n4. Use same libraries/frameworks\\n5. Follow security best practices (never log secrets)\\n6. Don't use one-letter variable names unless requested\\n\\nNever assume libraries are available - verify first.\\n\\n**Ambition vs. precision**:\\n- New projects → be creative and ambitious with implementation\\n- Existing codebases → be surgical and precise, respect surrounding code\\n- Don't change filenames or variables unnecessarily\\n- Don't add formatters/linters/tests to codebases that don't have them\\n</code_conventions>\\n\\n<testing>\\nAfter significant changes:\\n- Start testing as specific as possible to code changed, then broaden to build confidence\\n- Use self-verification: write unit tests, add output logs, or use debug statements to verify your solutions\\n- Run relevant test suite\\n- If tests fail, fix before continuing\\n- Check memory for test commands\\n- Run lint/typecheck if available (on precise targets when possible)\\n- For formatters: iterate max 3 times to get it right; if still failing, present correct solution and note formatting issue\\n- Suggest adding commands to memory if not found\\n- Don't fix unrelated bugs or test failures (not your responsibility)\\n</testing>\\n\\n<tool_usage>\\n- Default to using tools (ls, grep, view, agent, tests, web_fetch, etc.) rather than speculation whenever they can reduce uncertainty or unlock progress, even if it takes multiple tool calls.\\n- Search before assuming\\n- Read files before editing\\n- Always use absolute paths for file operations (editing, reading, writing)\\n- Use Agent tool for complex searches\\n- Run tools in parallel when safe (no dependencies)\\n- When making multiple independent bash calls, send them in a single message with multiple tool calls for parallel execution\\n- Summarize tool output for user (they don't see it)\\n- Never use `curl` through the bash tool it is not allowed use the fetch tool instead.\\n- Only use the tools you know exist.\\n\\n<bash_commands>\\n**CRITICAL**: The `description` parameter is REQUIRED for all bash tool calls. Always provide it.\\n\\nWhen running non-trivial bash commands (especially those that modify the system):\\n- Briefly explain what the command does and why you're running it\\n- This ensures the user understands potentially dangerous operations\\n- Simple read-only commands (ls, cat, etc.) don't need explanation\\n- Use `&` for background processes that won't stop on their own (e.g., `node server.js &`)\\n- Avoid interactive commands - use non-interactive versions (e.g., `npm init -y` not `npm init`)\\n- Combine related commands to save time (e.g., `git status && git diff HEAD && git log -n 3`)\\n</bash_commands>\\n</tool_usage>\\n\\n<proactiveness>\\nBalance autonomy with user intent:\\n- When asked to do something → do it fully (including ALL follow-ups and \\\"next steps\\\")\\n- Never describe what you'll do next - just do it\\n- When the user provides new information or clarification, incorporate it immediately and keep executing instead of stopping with an acknowledgement.\\n- Responding with only a plan, outline, or TODO list (or any other purely verbal response) is failure; you must execute the plan via tools whenever execution is possible.\\n- When asked how to approach → explain first, don't auto-implement\\n- After completing work → stop, don't explain (unless asked)\\n- Don't surprise user with unexpected actions\\n</proactiveness>\\n\\n<final_answers>\\nAdapt verbosity to match the work completed:\\n\\n**Default (under 4 lines)**:\\n- Simple questions or single-file changes\\n- Casual conversation, greetings, acknowledgements\\n- One-word answers when possible\\n\\n**More detail allowed (up to 10-15 lines)**:\\n- Large multi-file changes that need walkthrough\\n- Complex refactoring where rationale adds value\\n- Tasks where understanding the approach is important\\n- When mentioning unrelated bugs/issues found\\n- Suggesting logical next steps user might want\\n- Structure longer answers with Markdown sections and lists, and put all code, commands, and config in fenced code blocks.\\n\\n**What to include in verbose answers**:\\n- Brief summary of what was done and why\\n- Key files/functions changed (with `file:line` references)\\n- Any important decisions or tradeoffs made\\n- Next steps or things user should verify\\n- Issues found but not fixed\\n\\n**What to avoid**:\\n- Don't show full file contents unless explicitly asked\\n- Don't explain how to save files or copy code (user has access to your work)\\n- Don't use \\\"Here's what I did\\\" or \\\"Let me know if...\\\" style preambles/postambles\\n- Keep tone direct and factual, like handing off work to a teammate\\n</final_answers>\\n\\n<env>\\nWorking directory: /tmp/crush-test/TestCoderAgent/openrouter-kimi-k2/sourcegraph_tool\\nIs directory a git repo: no\\nPlatform: linux\\nToday's date: 1/1/2025\\n\\n</env>\\n\\n\\n\\n\\n\",\"role\":\"system\",\"cache_control\":{\"type\":\"ephemeral\"}},{\"content\":\"<system_reminder>This is a reminder that your todo list is currently empty. DO NOT mention this to the user explicitly because they are already aware.\\nIf you are working on tasks that would benefit from a todo list please use the \\\"todos\\\" tool to create one.\\nIf not, please feel free to ignore. Again do not mention this message to the user.</system_reminder>\",\"role\":\"user\"},{\"content\":\"use sourcegraph to search for 'func main' in Go repositories\",\"role\":\"user\"},{\"tool_calls\":[{\"id\":\"functions.sourcegraph:0\",\"function\":{\"arguments\":\"{\\\"query\\\": \\\"func main lang:go\\\"}\",\"name\":\"sourcegraph\"},\"type\":\"function\"}],\"role\":\"assistant\"},{\"content\":\"# Sourcegraph Search Results\\n\\nFound 30 matches across 30 results\\n(Result limit reached, try a more specific query)\\n\\n## Result 1: github.com/Balun-courses/deep_go/lessons/functions/defer_with_function/main.go\\n\\nURL: /r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/defer_with_function/main.go\\n\\n```\\n8| }\\n9| \\n10| func handle(string) {\\n11| \\tfmt.Println(\\\"3\\\")\\n12| }\\n13| \\n14| func process() {\\n15| \\tdefer handle(get())\\n16| \\tfmt.Println(\\\"2\\\")\\n17| }\\n18| func main() {\\n19| func main() {\\n20| \\tprocess()\\n21| }\\n22| \\n```\\n\\n```\\n0| package main\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func get() string {\\n6| \\tfmt.Println(\\\"1\\\")\\n7| \\treturn \\\"\\\"\\n8| }\\n9| \\n10| func handle(string) {\\n```\\n\\n```\\n3| import \\\"fmt\\\"\\n4| \\n5| func get() string {\\n6| \\tfmt.Println(\\\"1\\\")\\n7| \\treturn \\\"\\\"\\n8| }\\n9| \\n10| func handle(string) {\\n11| \\tfmt.Println(\\\"3\\\")\\n12| }\\n13| func process() {\\n14| func process() {\\n15| \\tdefer handle(get())\\n16| \\tfmt.Println(\\\"2\\\")\\n17| }\\n18| \\n19| func main() {\\n20| \\tprocess()\\n21| }\\n22| \\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| func get() string {\\n5| func get() string {\\n6| \\tfmt.Println(\\\"1\\\")\\n7| \\treturn \\\"\\\"\\n8| }\\n9| \\n10| func handle(string) {\\n11| \\tfmt.Println(\\\"3\\\")\\n12| }\\n13| \\n14| func process() {\\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func get() string {\\n6| \\tfmt.Println(\\\"1\\\")\\n7| \\treturn \\\"\\\"\\n8| }\\n9| func handle(string) {\\n10| func handle(string) {\\n11| \\tfmt.Println(\\\"3\\\")\\n12| }\\n13| \\n14| func process() {\\n15| \\tdefer handle(get())\\n16| \\tfmt.Println(\\\"2\\\")\\n17| }\\n18| \\n19| func main() {\\n```\\n\\n## Result 2: github.com/Balun-courses/deep_go/lessons/functions/high_order_function/main.go\\n\\nURL: /r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/high_order_function/main.go\\n\\n```\\n3| import \\\"fmt\\\"\\n4| \\n5| func forEach(data []int, fn func(int) int) []int {\\n6| \\tnewData := make([]int, 0, len(data))\\n7| \\tfor _, value := range data {\\n8| \\t\\tnewData = append(newData, fn(value))\\n9| \\t}\\n10| \\n11| \\treturn newData\\n12| }\\n13| func main() {\\n14| func main() {\\n15| \\tvar data = []int{1, 2, 3, 4}\\n16| \\tvar newData = forEach(data, func(value int) int {\\n17| \\t\\treturn (value * value)\\n18| \\t})\\n19| \\n20| \\tfmt.Println(data)\\n21| \\tfmt.Println(newData)\\n22| }\\n23| \\n```\\n\\n```\\n5| func forEach(data []int, fn func(int) int) []int {\\n6| \\tnewData := make([]int, 0, len(data))\\n7| \\tfor _, value := range data {\\n8| \\t\\tnewData = append(newData, fn(value))\\n9| \\t}\\n10| \\n11| \\treturn newData\\n12| }\\n13| \\n14| func main() {\\n15| \\tvar newData = forEach(data, func(value int) int {\\n16| \\tvar newData = forEach(data, func(value int) int {\\n17| \\t\\treturn (value * value)\\n18| \\t})\\n19| \\n20| \\tfmt.Println(data)\\n21| \\tfmt.Println(newData)\\n22| }\\n23| \\n```\\n\\n```\\n0| package main\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func forEach(data []int, fn func(int) int) []int {\\n6| \\tnewData := make([]int, 0, len(data))\\n7| \\tfor _, value := range data {\\n8| \\t\\tnewData = append(newData, fn(value))\\n9| \\t}\\n10| \\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| func forEach(data []int, fn func(int) int) []int {\\n5| func forEach(data []int, fn func(int) int) []int {\\n6| \\tnewData := make([]int, 0, len(data))\\n7| \\tfor _, value := range data {\\n8| \\t\\tnewData = append(newData, fn(value))\\n9| \\t}\\n10| \\n11| \\treturn newData\\n12| }\\n13| \\n14| func main() {\\n```\\n\\n## Result 3: github.com/Balun-courses/deep_go/lessons/functions/composition/main.go\\n\\nURL: /r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/composition/main.go\\n\\n```\\n12| \\n13| func compose(fn ...func(int) int) func(int) int {\\n14| \\treturn func(value int) int {\\n15| \\t\\tfor _, v := range fn {\\n16| \\t\\t\\tvalue = v(value)\\n17| \\t\\t}\\n18| \\n19| \\t\\treturn value\\n20| \\t}\\n21| }\\n22| func main() {\\n23| func main() {\\n24| \\tfn := compose(sqr, neg, sqr)\\n25| \\tfmt.Println(fn(4))\\n26| }\\n27| \\n```\\n\\n```\\n0| package main\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func sqr(number int) int {\\n6| \\treturn number * number\\n7| }\\n8| \\n9| func neg(number int) int {\\n10| \\treturn -number\\n```\\n\\n```\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func sqr(number int) int {\\n6| \\treturn number * number\\n7| }\\n8| \\n9| func neg(number int) int {\\n10| \\treturn -number\\n11| }\\n12| func compose(fn ...func(int) int) func(int) int {\\n13| func compose(fn ...func(int) int) func(int) int {\\n14| \\treturn func(value int) int {\\n15| \\t\\tfor _, v := range fn {\\n16| \\t\\t\\tvalue = v(value)\\n17| \\t\\t}\\n18| \\n19| \\t\\treturn value\\n20| \\t}\\n21| }\\n22| \\n```\\n\\n```\\n3| import \\\"fmt\\\"\\n4| \\n5| func sqr(number int) int {\\n6| \\treturn number * number\\n7| }\\n8| \\n9| func neg(number int) int {\\n10| \\treturn -number\\n11| }\\n12| \\n13| \\treturn func(value int) int {\\n14| \\treturn func(value int) int {\\n15| \\t\\tfor _, v := range fn {\\n16| \\t\\t\\tvalue = v(value)\\n17| \\t\\t}\\n18| \\n19| \\t\\treturn value\\n20| \\t}\\n21| }\\n22| \\n23| func main() {\\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| func sqr(number int) int {\\n5| func sqr(number int) int {\\n6| \\treturn number * number\\n7| }\\n8| \\n9| func neg(number int) int {\\n10| \\treturn -number\\n11| }\\n12| \\n13| func compose(fn ...func(int) int) func(int) int {\\n14| \\treturn func(value int) int {\\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func sqr(number int) int {\\n6| \\treturn number * number\\n7| }\\n8| func neg(number int) int {\\n9| func neg(number int) int {\\n10| \\treturn -number\\n11| }\\n12| \\n13| func compose(fn ...func(int) int) func(int) int {\\n14| \\treturn func(value int) int {\\n15| \\t\\tfor _, v := range fn {\\n16| \\t\\t\\tvalue = v(value)\\n17| \\t\\t}\\n18| \\n```\\n\\n## Result 4: github.com/Balun-courses/deep_go/lessons/functions/defer_evaluation_moment/main.go\\n\\nURL: /r/github.com/Balun-courses/deep_go/-/blob/lessons/functions/defer_evaluation_moment/main.go\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| func main() {\\n5| func main() {\\n6| \\tvar f func()\\n7| \\tdefer f()\\n8| \\n9| \\tf = func() {\\n10| \\t\\tfmt.Println(true)\\n11| \\t}\\n12| }\\n13| \\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| \\tvar f func()\\n6| \\tvar f func()\\n7| \\tdefer f()\\n8| \\n9| \\tf = func() {\\n10| \\t\\tfmt.Println(true)\\n11| \\t}\\n12| }\\n13| \\n```\\n\\n```\\n0| package main\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func main() {\\n6| \\tvar f func()\\n7| \\tdefer f()\\n8| \\n9| \\tf = func() {\\n10| \\t\\tfmt.Println(true)\\n```\\n\\n```\\n1| package main\\n2| \\n3| import \\\"fmt\\\"\\n4| \\n5| func main() {\\n6| \\tvar f func()\\n7| \\tdefer f()\\n8| \\tf = func() {\\n9| \\tf = func() {\\n10| \\t\\tfmt.Println(true)\\n11| \\t}\\n12| }\\n13| \\n```\\n\\n## Result 5: github.com/Balun-courses/deep_go/lessons/contexts/after_done/main.go\\n\\nURL: /r/github.com/Balun-courses/deep_go/-/blob/lessons/contexts/after_done/main.go\\n\\n```\\n9| // context.AfterFunc\\n10| \\n11| func WithCtxAfterFunc(ctx context.Context, action func()) {\\n12| \\tif action != nil {\\n13| \\t\\tgo func() {\\n14| \\t\\t\\t<-ctx.Done()\\n15| \\t\\t\\taction()\\n16| \\t\\t}()\\n17| \\t}\\n18| }\\n19| func main() {\\n20| func main() {\\n21| \\tctx, cancel := context.WithCancel(context.Background())\\n22| \\tWithCtxAfterFunc(ctx, func() {\\n23| \\t\\tfmt.Println(\\\"after\\\")\\n24| \\t})\\n25| \\n26| \\tcancel()\\n27| \\n28| \\ttime.Sleep(100 * time.Millisecond)\\n29| }\\n```\\n\\n```\\n11| func WithCtxAfterFunc(ctx context.Context, action func()) {\\n12| \\tif action != nil {\\n13| \\t\\tgo func() {\\n14| \\t\\t\\t<-ctx.Done()\\n15| \\t\\t\\taction()\\n16| \\t\\t}()\\n17| \\t}\\n18| }\\n19| \\n20| func main() {\\n21| \\tWithCtxAfterFunc(ctx, func() {\\n22| \\tWithCtxAfterFunc(ctx, func() {\\n23| \\t\\tfmt.Println(\\\"after\\\")\\n24| \\t})\\n25| \\n26| \\tcancel()\\n27| \\n28| \\ttime.Sleep(100 * time.Millisecond)\\n29| }\\n30| \\n```\\n\\n```\\n0| package main\\n1| package main\\n2| \\n3| import (\\n4| \\t\\\"context\\\"\\n5| \\t\\\"fmt\\\"\\n6| \\t\\\"time\\\"\\n7| )\\n8| \\n9| // context.AfterFunc\\n10| \\n```\\n\\n```\\n1| package main\\n2| \\n3| import (\\n4| \\t\\\"context\\\"\\n5| \\t\\\"fmt\\\"\\n6| \\t\\\"time\\\"\\n7| )\\n8| // context.AfterFunc\\n9| // context.AfterFunc\\n10| \\n11| func WithCtxAfterFunc(ctx context.Context, action func()) {\\n12| \\tif action != nil {\\n13| \\t\\tgo func() {\\n14| \\t\\t\\t<-ctx.Done()\\n15| \\t\\t\\taction()\\n16| \\t\\t}()\\n17| \\t}\\n18| }\\n```\\n\\n```\\n1| package main\\n2| \\n3| import (\\n4| \\t\\\"context\\\"\\n5| \\t\\\"fmt\\\"\\n6| \\t\\\"time\\\"\\n7| )\\n8| \\n9| // context.AfterFunc\\n10| func WithCtxAfterFunc(ctx context.Context, action func()) {\\n11| func WithCtxAfterFunc(ctx context.Context, action func()) {\\n12| \\tif action != nil {\\n13| \\t\\tgo func() {\\n14| \\t\\t\\t<-ctx.Done()\\n15| \\t\\t\\taction()\\n16| \\t\\t}()\\n17| \\t}\\n18| }\\n19| \\n20| func main() {\\n```\\n\\n\",\"tool_call_id\":\"functions.sourcegraph:0\",\"role\":\"tool\"},{\"tool_calls\":[{\"id\":\"functions.sourcegraph:1\",\"function\":{\"arguments\":\"{\\\"query\\\": \\\": \\\\\\\"func main lang:go type:file\\\\\\\"}\\\"}\",\"name\":\"sourcegraph\"},\"type\":\"function\"}],\"role\":\"assistant\"},{\"content\":\"# Sourcegraph Search Results\\n\\nFound 0 matches across 0 results\\n\\nNo results found. Try a different query.\\n\",\"tool_call_id\":\"functions.sourcegraph:1\",\"role\":\"tool\"},{\"tool_calls\":[{\"id\":\"functions.sourcegraph:2\",\"function\":{\"arguments\":\"{\\\"query\\\": \\\":E\\\"}\",\"name\":\"sourcegraph\"},\"type\":\"function\",\"cache_control\":{\"type\":\"ephemeral\"}}],\"role\":\"assistant\"},{\"content\":\"# Sourcegraph Search Results\\n\\nFound 30 matches across 30 results\\n(Result limit reached, try a more specific query)\\n\\n## Result 1: github.com/astral-sh/uv/crates/uv-distribution/src/error.rs\\n\\nURL: /r/github.com/astral-sh/uv/-/blob/crates/uv-distribution/src/error.rs\\n\\n```\\n179| distribution: String,\\n180| actual: String,\\n181| },\\n182| \\n183| #[error(\\\"Hash-checking is not supported for local directories: `{0}`\\\")]\\n184| HashesNotSupportedSourceTree(String),\\n185| \\n186| #[error(\\\"Hash-checking is not supported for Git repositories: `{0}`\\\")]\\n187| HashesNotSupportedGit(String),\\n188| }\\n189| impl From<reqwest::Error> for Error {\\n190| impl From<reqwest::Error> for Error {\\n191| fn from(error: reqwest::Error) -> Self {\\n192| Self::Reqwest(WrappedReqwestError::from(error))\\n193| }\\n194| }\\n195| \\n196| impl From<reqwest_middleware::Error> for Error {\\n197| fn from(error: reqwest_middleware::Error) -> Self {\\n198| match error {\\n199| reqwest_middleware::Error::Middleware(error) => Self::ReqwestMiddlewareError(error),\\n```\\n\\n```\\n180| actual: String,\\n181| },\\n182| \\n183| #[error(\\\"Hash-checking is not supported for local directories: `{0}`\\\")]\\n184| HashesNotSupportedSourceTree(String),\\n185| \\n186| #[error(\\\"Hash-checking is not supported for Git repositories: `{0}`\\\")]\\n187| HashesNotSupportedGit(String),\\n188| }\\n189| \\n190| fn from(error: reqwest::Error) -> Self {\\n191| fn from(error: reqwest::Error) -> Self {\\n192| Self::Reqwest(WrappedReqwestError::from(error))\\n193| }\\n194| }\\n195| \\n196| impl From<reqwest_middleware::Error> for Error {\\n197| fn from(error: reqwest_middleware::Error) -> Self {\\n198| match error {\\n199| reqwest_middleware::Error::Middleware(error) => Self::ReqwestMiddlewareError(error),\\n200| reqwest_middleware::Error::Reqwest(error) => {\\n```\\n\\n```\\n1| use std::path::PathBuf;\\n2| \\n3| use owo_colors::OwoColorize;\\n4| use tokio::task::JoinError;\\n5| use zip::result::ZipError;\\n6| \\n7| use uv_cache::Error as CacheError;\\n8| use uv_cache::Error as CacheError;\\n9| use uv_client::WrappedReqwestError;\\n10| use uv_distribution_filename::{WheelFilename, WheelFilenameError};\\n11| use uv_distribution_types::{InstalledDist, InstalledDistError, IsBuildBackendError};\\n12| use uv_fs::Simplified;\\n13| use uv_git::GitError;\\n14| use uv_normalize::PackageName;\\n15| use uv_pep440::{Version, VersionSpecifiers};\\n16| use uv_platform_tags::Platform;\\n17| use uv_pypi_types::{HashAlgorithm, HashDigest};\\n```\\n\\n```\\n10| use uv_distribution_filename::{WheelFilename, WheelFilenameError};\\n11| use uv_distribution_types::{InstalledDist, InstalledDistError, IsBuildBackendError};\\n12| use uv_fs::Simplified;\\n13| use uv_git::GitError;\\n14| use uv_normalize::PackageName;\\n15| use uv_pep440::{Version, VersionSpecifiers};\\n16| use uv_platform_tags::Platform;\\n17| use uv_pypi_types::{HashAlgorithm, HashDigest};\\n18| use uv_redacted::DisplaySafeUrl;\\n19| use uv_types::AnyErrorBuild;\\n20| #[derive(Debug, thiserror::Error)]\\n21| #[derive(Debug, thiserror::Error)]\\n22| pub enum Error {\\n23| #[error(\\\"Building source distributions is disabled\\\")]\\n24| NoBuild,\\n25| \\n26| // Network error\\n27| #[error(transparent)]\\n28| InvalidUrl(#[from] uv_distribution_types::ToUrlError),\\n29| #[error(\\\"Expected a file URL, but received: {0}\\\")]\\n30| NonFileUrl(DisplaySafeUrl),\\n```\\n\\n```\\n25| \\n26| // Network error\\n27| #[error(transparent)]\\n28| InvalidUrl(#[from] uv_distribution_types::ToUrlError),\\n29| #[error(\\\"Expected a file URL, but received: {0}\\\")]\\n30| NonFileUrl(DisplaySafeUrl),\\n31| #[error(transparent)]\\n32| Git(#[from] uv_git::GitResolverError),\\n33| #[error(transparent)]\\n34| Reqwest(#[from] WrappedReqwestError),\\n35| Client(#[from] uv_client::Error),\\n36| Client(#[from] uv_client::Error),\\n37| \\n38| // Cache writing error\\n39| #[error(\\\"Failed to read from the distribution cache\\\")]\\n40| CacheRead(#[source] std::io::Error),\\n41| #[error(\\\"Failed to write to the distribution cache\\\")]\\n42| CacheWrite(#[source] std::io::Error),\\n43| #[error(\\\"Failed to acquire lock on the distribution cache\\\")]\\n44| CacheLock(#[source] CacheError),\\n45| #[error(\\\"Failed to deserialize cache entry\\\")]\\n```\\n\\n```\\n29| #[error(\\\"Expected a file URL, but received: {0}\\\")]\\n30| NonFileUrl(DisplaySafeUrl),\\n31| #[error(transparent)]\\n32| Git(#[from] uv_git::GitResolverError),\\n33| #[error(transparent)]\\n34| Reqwest(#[from] WrappedReqwestError),\\n35| #[error(transparent)]\\n36| Client(#[from] uv_client::Error),\\n37| \\n38| // Cache writing error\\n39| CacheRead(#[source] std::io::Error),\\n40| CacheRead(#[source] std::io::Error),\\n41| #[error(\\\"Failed to write to the distribution cache\\\")]\\n42| CacheWrite(#[source] std::io::Error),\\n43| #[error(\\\"Failed to acquire lock on the distribution cache\\\")]\\n44| CacheLock(#[source] CacheError),\\n45| #[error(\\\"Failed to deserialize cache entry\\\")]\\n46| CacheDecode(#[from] rmp_serde::decode::Error),\\n47| #[error(\\\"Failed to serialize cache entry\\\")]\\n48| CacheEncode(#[from] rmp_serde::encode::Error),\\n49| #[error(\\\"Failed to walk the distribution cache\\\")]\\n```\\n\\n```\\n31| #[error(transparent)]\\n32| Git(#[from] uv_git::GitResolverError),\\n33| #[error(transparent)]\\n34| Reqwest(#[from] WrappedReqwestError),\\n35| #[error(transparent)]\\n36| Client(#[from] uv_client::Error),\\n37| \\n38| // Cache writing error\\n39| #[error(\\\"Failed to read from the distribution cache\\\")]\\n40| CacheRead(#[source] std::io::Error),\\n41| CacheWrite(#[source] std::io::Error),\\n42| CacheWrite(#[source] std::io::Error),\\n43| #[error(\\\"Failed to acquire lock on the distribution cache\\\")]\\n44| CacheLock(#[source] CacheError),\\n45| #[error(\\\"Failed to deserialize cache entry\\\")]\\n46| CacheDecode(#[from] rmp_serde::decode::Error),\\n47| #[error(\\\"Failed to serialize cache entry\\\")]\\n48| CacheEncode(#[from] rmp_serde::encode::Error),\\n49| #[error(\\\"Failed to walk the distribution cache\\\")]\\n50| CacheWalk(#[source] walkdir::Error),\\n51| #[error(transparent)]\\n```\\n\\n```\\n35| #[error(transparent)]\\n36| Client(#[from] uv_client::Error),\\n37| \\n38| // Cache writing error\\n39| #[error(\\\"Failed to read from the distribution cache\\\")]\\n40| CacheRead(#[source] std::io::Error),\\n41| #[error(\\\"Failed to write to the distribution cache\\\")]\\n42| CacheWrite(#[source] std::io::Error),\\n43| #[error(\\\"Failed to acquire lock on the distribution cache\\\")]\\n44| CacheLock(#[source] CacheError),\\n45| CacheDecode(#[from] rmp_serde::decode::Error),\\n46| CacheDecode(#[from] rmp_serde::decode::Error),\\n47| #[error(\\\"Failed to serialize cache entry\\\")]\\n48| CacheEncode(#[from] rmp_serde::encode::Error),\\n49| #[error(\\\"Failed to walk the distribution cache\\\")]\\n50| CacheWalk(#[source] walkdir::Error),\\n51| #[error(transparent)]\\n52| CacheInfo(#[from] uv_cache_info::CacheInfoError),\\n53| \\n54| // Build error\\n55| #[error(transparent)]\\n```\\n\\n```\\n37| \\n38| // Cache writing error\\n39| #[error(\\\"Failed to read from the distribution cache\\\")]\\n40| CacheRead(#[source] std::io::Error),\\n41| #[error(\\\"Failed to write to the distribution cache\\\")]\\n42| CacheWrite(#[source] std::io::Error),\\n43| #[error(\\\"Failed to acquire lock on the distribution cache\\\")]\\n44| CacheLock(#[source] CacheError),\\n45| #[error(\\\"Failed to deserialize cache entry\\\")]\\n46| CacheDecode(#[from] rmp_serde::decode::Error),\\n47| CacheEncode(#[from] rmp_serde::encode::Error),\\n48| CacheEncode(#[from] rmp_serde::encode::Error),\\n49| #[error(\\\"Failed to walk the distribution cache\\\")]\\n50| CacheWalk(#[source] walkdir::Error),\\n51| #[error(transparent)]\\n52| CacheInfo(#[from] uv_cache_info::CacheInfoError),\\n53| \\n54| // Build error\\n55| #[error(transparent)]\\n56| Build(AnyErrorBuild),\\n57| #[error(\\\"Built wheel has an invalid filename\\\")]\\n```\\n\\n```\\n39| #[error(\\\"Failed to read from the distribution cache\\\")]\\n40| CacheRead(#[source] std::io::Error),\\n41| #[error(\\\"Failed to write to the distribution cache\\\")]\\n42| CacheWrite(#[source] std::io::Error),\\n43| #[error(\\\"Failed to acquire lock on the distribution cache\\\")]\\n44| CacheLock(#[source] CacheError),\\n45| #[error(\\\"Failed to deserialize cache entry\\\")]\\n46| CacheDecode(#[from] rmp_serde::decode::Error),\\n47| #[error(\\\"Failed to serialize cache entry\\\")]\\n48| CacheEncode(#[from] rmp_serde::encode::Error),\\n49| CacheWalk(#[source] walkdir::Error),\\n50| CacheWalk(#[source] walkdir::Error),\\n51| #[error(transparent)]\\n52| CacheInfo(#[from] uv_cache_info::CacheInfoError),\\n53| \\n54| // Build error\\n55| #[error(transparent)]\\n56| Build(AnyErrorBuild),\\n57| #[error(\\\"Built wheel has an invalid filename\\\")]\\n58| WheelFilename(#[from] WheelFilenameError),\\n59| #[error(\\\"Package metadata name `{metadata}` does not match given name `{given}`\\\")]\\n```\\n\\n```\\n101| python_platform.os(),\\n102| python_platform.arch(),\\n103| )]\\n104| BuiltWheelIncompatibleTargetPlatform {\\n105| filename: WheelFilename,\\n106| python_platform: Platform,\\n107| python_version: (u8, u8),\\n108| },\\n109| #[error(\\\"Failed to parse metadata from built wheel\\\")]\\n110| Metadata(#[from] uv_pypi_types::MetadataError),\\n111| WheelMetadata(PathBuf, #[source] Box<uv_metadata::Error>),\\n112| WheelMetadata(PathBuf, #[source] Box<uv_metadata::Error>),\\n113| #[error(\\\"Failed to read metadata from installed package `{0}`\\\")]\\n114| ReadInstalled(Box<InstalledDist>, #[source] InstalledDistError),\\n115| #[error(\\\"Failed to read zip archive from built wheel\\\")]\\n116| Zip(#[from] ZipError),\\n117| #[error(\\\"Failed to extract archive: {0}\\\")]\\n118| Extract(String, #[source] uv_extract::Error),\\n119| #[error(\\\"The source distribution is missing a `PKG-INFO` file\\\")]\\n120| MissingPkgInfo,\\n121| #[error(\\\"The source distribution `{}` has no subdirectory `{}`\\\", _0, _1.display())]\\n```\\n\\n```\\n107| python_version: (u8, u8),\\n108| },\\n109| #[error(\\\"Failed to parse metadata from built wheel\\\")]\\n110| Metadata(#[from] uv_pypi_types::MetadataError),\\n111| #[error(\\\"Failed to read metadata: `{}`\\\", _0.user_display())]\\n112| WheelMetadata(PathBuf, #[source] Box<uv_metadata::Error>),\\n113| #[error(\\\"Failed to read metadata from installed package `{0}`\\\")]\\n114| ReadInstalled(Box<InstalledDist>, #[source] InstalledDistError),\\n115| #[error(\\\"Failed to read zip archive from built wheel\\\")]\\n116| Zip(#[from] ZipError),\\n117| Extract(String, #[source] uv_extract::Error),\\n118| Extract(String, #[source] uv_extract::Error),\\n119| #[error(\\\"The source distribution is missing a `PKG-INFO` file\\\")]\\n120| MissingPkgInfo,\\n121| #[error(\\\"The source distribution `{}` has no subdirectory `{}`\\\", _0, _1.display())]\\n122| MissingSubdirectory(DisplaySafeUrl, PathBuf),\\n123| #[error(\\\"The source distribution `{0}` is missing Git LFS artifacts.\\\")]\\n124| MissingGitLfsArtifacts(DisplaySafeUrl, #[source] GitError),\\n125| #[error(\\\"Failed to extract static metadata from `PKG-INFO`\\\")]\\n126| PkgInfo(#[source] uv_pypi_types::MetadataError),\\n127| #[error(\\\"The source distribution is missing a `pyproject.toml` file\\\")]\\n```\\n\\n```\\n129| #[error(\\\"Failed to extract static metadata from `pyproject.toml`\\\")]\\n130| PyprojectToml(#[source] uv_pypi_types::MetadataError),\\n131| #[error(transparent)]\\n132| MetadataLowering(#[from] MetadataError),\\n133| #[error(\\\"Distribution not found at: {0}\\\")]\\n134| NotFound(DisplaySafeUrl),\\n135| #[error(\\\"Attempted to re-extract the source distribution for `{}`, but the {} hash didn't match. Run `{}` to clear the cache.\\\", _0, _1, \\\"uv cache clean\\\".green())]\\n136| CacheHeal(String, HashAlgorithm),\\n137| #[error(\\\"The source distribution requires Python {0}, but {1} is installed\\\")]\\n138| RequiresPython(VersionSpecifiers, Version),\\n139| BaseInterpreter(#[source] std::io::Error),\\n140| BaseInterpreter(#[source] std::io::Error),\\n141| \\n142| /// A generic request middleware error happened while making a request.\\n143| /// Refer to the error message for more details.\\n144| #[error(transparent)]\\n145| ReqwestMiddlewareError(#[from] anyhow::Error),\\n146| \\n147| /// Should not occur; only seen when another task panicked.\\n148| #[error(\\\"The task executor is broken, did some other task panic?\\\")]\\n149| Join(#[from] JoinError),\\n```\\n\\n```\\n134| NotFound(DisplaySafeUrl),\\n135| #[error(\\\"Attempted to re-extract the source distribution for `{}`, but the {} hash didn't match. Run `{}` to clear the cache.\\\", _0, _1, \\\"uv cache clean\\\".green())]\\n136| CacheHeal(String, HashAlgorithm),\\n137| #[error(\\\"The source distribution requires Python {0}, but {1} is installed\\\")]\\n138| RequiresPython(VersionSpecifiers, Version),\\n139| #[error(\\\"Failed to identify base Python interpreter\\\")]\\n140| BaseInterpreter(#[source] std::io::Error),\\n141| \\n142| /// A generic request middleware error happened while making a request.\\n143| /// Refer to the error message for more details.\\n144| ReqwestMiddlewareError(#[from] anyhow::Error),\\n145| ReqwestMiddlewareError(#[from] anyhow::Error),\\n146| \\n147| /// Should not occur; only seen when another task panicked.\\n148| #[error(\\\"The task executor is broken, did some other task panic?\\\")]\\n149| Join(#[from] JoinError),\\n150| \\n151| /// An I/O error that occurs while exhausting a reader to compute a hash.\\n152| #[error(\\\"Failed to hash distribution\\\")]\\n153| HashExhaustion(#[source] std::io::Error),\\n154| \\n```\\n\\n```\\n142| /// A generic request middleware error happened while making a request.\\n143| /// Refer to the error message for more details.\\n144| #[error(transparent)]\\n145| ReqwestMiddlewareError(#[from] anyhow::Error),\\n146| \\n147| /// Should not occur; only seen when another task panicked.\\n148| #[error(\\\"The task executor is broken, did some other task panic?\\\")]\\n149| Join(#[from] JoinError),\\n150| \\n151| /// An I/O error that occurs while exhausting a reader to compute a hash.\\n152| HashExhaustion(#[source] std::io::Error),\\n153| HashExhaustion(#[source] std::io::Error),\\n154| \\n155| #[error(\\\"Hash mismatch for `{distribution}`\\\\n\\\\nExpected:\\\\n{expected}\\\\n\\\\nComputed:\\\\n{actual}\\\")]\\n156| MismatchedHashes {\\n157| distribution: String,\\n158| expected: String,\\n159| actual: String,\\n160| },\\n161| \\n162| #[error(\\n```\\n\\n```\\n185| \\n186| #[error(\\\"Hash-checking is not supported for Git repositories: `{0}`\\\")]\\n187| HashesNotSupportedGit(String),\\n188| }\\n189| \\n190| impl From<reqwest::Error> for Error {\\n191| fn from(error: reqwest::Error) -> Self {\\n192| Self::Reqwest(WrappedReqwestError::from(error))\\n193| }\\n194| }\\n195| impl From<reqwest_middleware::Error> for Error {\\n196| impl From<reqwest_middleware::Error> for Error {\\n197| fn from(error: reqwest_middleware::Error) -> Self {\\n198| match error {\\n199| reqwest_middleware::Error::Middleware(error) => Self::ReqwestMiddlewareError(error),\\n200| reqwest_middleware::Error::Reqwest(error) => {\\n201| Self::Reqwest(WrappedReqwestError::from(error))\\n202| }\\n203| }\\n204| }\\n205| }\\n```\\n\\n```\\n186| #[error(\\\"Hash-checking is not supported for Git repositories: `{0}`\\\")]\\n187| HashesNotSupportedGit(String),\\n188| }\\n189| \\n190| impl From<reqwest::Error> for Error {\\n191| fn from(error: reqwest::Error) -> Self {\\n192| Self::Reqwest(WrappedReqwestError::from(error))\\n193| }\\n194| }\\n195| \\n196| fn from(error: reqwest_middleware::Error) -> Self {\\n197| fn from(error: reqwest_middleware::Error) -> Self {\\n198| match error {\\n199| reqwest_middleware::Error::Middleware(error) => Self::ReqwestMiddlewareError(error),\\n200| reqwest_middleware::Error::Reqwest(error) => {\\n201| Self::Reqwest(WrappedReqwestError::from(error))\\n202| }\\n203| }\\n204| }\\n205| }\\n206| \\n```\\n\\n```\\n188| }\\n189| \\n190| impl From<reqwest::Error> for Error {\\n191| fn from(error: reqwest::Error) -> Self {\\n192| Self::Reqwest(WrappedReqwestError::from(error))\\n193| }\\n194| }\\n195| \\n196| impl From<reqwest_middleware::Error> for Error {\\n197| fn from(error: reqwest_middleware::Error) -> Self {\\n198| reqwest_middleware::Error::Middleware(error) => Self::ReqwestMiddlewareError(error),\\n199| reqwest_middleware::Error::Middleware(error) => Self::ReqwestMiddlewareError(error),\\n200| reqwest_middleware::Error::Reqwest(error) => {\\n201| Self::Reqwest(WrappedReqwestError::from(error))\\n202| }\\n203| }\\n204| }\\n205| }\\n206| \\n207| impl IsBuildBackendError for Error {\\n208| fn is_build_backend_error(&self) -> bool {\\n```\\n\\n```\\n189| \\n190| impl From<reqwest::Error> for Error {\\n191| fn from(error: reqwest::Error) -> Self {\\n192| Self::Reqwest(WrappedReqwestError::from(error))\\n193| }\\n194| }\\n195| \\n196| impl From<reqwest_middleware::Error> for Error {\\n197| fn from(error: reqwest_middleware::Error) -> Self {\\n198| match error {\\n199| reqwest_middleware::Error::Reqwest(error) => {\\n200| reqwest_middleware::Error::Reqwest(error) => {\\n201| Self::Reqwest(WrappedReqwestError::from(error))\\n202| }\\n203| }\\n204| }\\n205| }\\n206| \\n207| impl IsBuildBackendError for Error {\\n208| fn is_build_backend_error(&self) -> bool {\\n209| match self {\\n```\\n\\n## Result 2: github.com/astral-sh/uv/crates/uv-client/src/cached_client.rs\\n\\nURL: /r/github.com/astral-sh/uv/-/blob/crates/uv-client/src/cached_client.rs\\n\\n```\\n151| }\\n152| }\\n153| \\n154| impl<CallbackError: std::error::Error + 'static> From<ErrorKind>\\n155| for CachedClientError<CallbackError>\\n156| {\\n157| fn from(error: ErrorKind) -> Self {\\n158| Self::Client(error.into())\\n159| }\\n160| }\\n161| impl<E: Into<Self> + std::error::Error + 'static> From<CachedClientError<E>> for Error {\\n162| impl<E: Into<Self> + std::error::Error + 'static> From<CachedClientError<E>> for Error {\\n163| /// Attach retry error context, if there were retries.\\n164| fn from(error: CachedClientError<E>) -> Self {\\n165| match error {\\n166| CachedClientError::Client(error) => error,\\n167| CachedClientError::Callback {\\n168| retries,\\n169| err,\\n170| duration,\\n171| } => Self::new(err.into().into_kind(), retries, duration),\\n```\\n\\n```\\n59| }\\n60| \\n61| impl<T: Serialize + DeserializeOwned + Send + 'static> Cacheable for SerdeCacheable<T> {\\n62| type Target = T;\\n63| \\n64| fn from_aligned_bytes(bytes: AlignedVec) -> Result<T, Error> {\\n65| Ok(rmp_serde::from_slice::<T>(&bytes).map_err(ErrorKind::Decode)?)\\n66| }\\n67| \\n68| fn to_bytes(&self) -> Result<Cow<'_, [u8]>, Error> {\\n69| rmp_serde::to_vec(&self.inner).map_err(ErrorKind::Encode)?,\\n70| rmp_serde::to_vec(&self.inner).map_err(ErrorKind::Encode)?,\\n71| ))\\n72| }\\n73| \\n74| fn into_target(self) -> Self::Target {\\n75| self.inner\\n76| }\\n77| }\\n78| \\n79| /// All `OwnedArchive` values are cacheable.\\n```\\n\\n```\\n93| fn to_bytes(&self) -> Result<Cow<'_, [u8]>, Error> {\\n94| Ok(Cow::from(Self::as_bytes(self)))\\n95| }\\n96| \\n97| fn into_target(self) -> Self::Target {\\n98| self\\n99| }\\n100| }\\n101| \\n102| /// Dispatch type: Either a cached client error or a (user specified) error from the callback.\\n103| pub enum CachedClientError<CallbackError: std::error::Error + 'static> {\\n104| pub enum CachedClientError<CallbackError: std::error::Error + 'static> {\\n105| /// The client tracks retries internally.\\n106| Client(Error),\\n107| /// Track retries before a callback explicitly, as we can't attach them to the callback error\\n108| /// type.\\n109| Callback {\\n110| retries: u32,\\n111| err: CallbackError,\\n112| duration: Duration,\\n113| },\\n```\\n\\n```\\n105| /// The client tracks retries internally.\\n106| Client(Error),\\n107| /// Track retries before a callback explicitly, as we can't attach them to the callback error\\n108| /// type.\\n109| Callback {\\n110| retries: u32,\\n111| err: CallbackError,\\n112| duration: Duration,\\n113| },\\n114| }\\n115| impl<CallbackError: std::error::Error + 'static> CachedClientError<CallbackError> {\\n116| impl<CallbackError: std::error::Error + 'static> CachedClientError<CallbackError> {\\n117| /// Attach the combined number of retries to the error context, discarding the previous count.\\n118| fn with_retries(self, retries: u32) -> Self {\\n119| match self {\\n120| Self::Client(err) => Self::Client(err.with_retries(retries)),\\n121| Self::Callback {\\n122| retries: _,\\n123| err,\\n124| duration,\\n125| } => Self::Callback {\\n```\\n\\n```\\n129| },\\n130| }\\n131| }\\n132| \\n133| fn retries(&self) -> u32 {\\n134| match self {\\n135| Self::Client(err) => err.retries(),\\n136| Self::Callback { retries, .. } => *retries,\\n137| }\\n138| }\\n139| fn error(&self) -> &(dyn std::error::Error + 'static) {\\n140| fn error(&self) -> &(dyn std::error::Error + 'static) {\\n141| match self {\\n142| Self::Client(err) => err,\\n143| Self::Callback { err, .. } => err,\\n144| }\\n145| }\\n146| }\\n147| \\n148| impl<CallbackError: std::error::Error + 'static> From<Error> for CachedClientError<CallbackError> {\\n149| fn from(error: Error) -> Self {\\n```\\n\\n```\\n137| }\\n138| }\\n139| \\n140| fn error(&self) -> &(dyn std::error::Error + 'static) {\\n141| match self {\\n142| Self::Client(err) => err,\\n143| Self::Callback { err, .. } => err,\\n144| }\\n145| }\\n146| }\\n147| impl<CallbackError: std::error::Error + 'static> From<Error> for CachedClientError<CallbackError> {\\n148| impl<CallbackError: std::error::Error + 'static> From<Error> for CachedClientError<CallbackError> {\\n149| fn from(error: Error) -> Self {\\n150| Self::Client(error)\\n151| }\\n152| }\\n153| \\n154| impl<CallbackError: std::error::Error + 'static> From<ErrorKind>\\n155| for CachedClientError<CallbackError>\\n156| {\\n157| fn from(error: ErrorKind) -> Self {\\n```\\n\\n\",\"tool_call_id\":\"functions.sourcegraph:2\",\"role\":\"tool\"}],\"model\":\"moonshotai/kimi-k2-0905\",\"max_tokens\":10000,\"stream_options\":{\"include_usage\":true},\"tool_choice\":\"auto\",\"tools\":[{\"function\":{\"name\":\"bash\",\"strict\":false,\"description\":\"Executes bash commands with automatic background conversion for long-running tasks.\\n\\n<cross_platform>\\nUses mvdan/sh interpreter (Bash-compatible on all platforms including Windows).\\nUse forward slashes for paths: \\\"ls C:/foo/bar\\\" not \\\"ls C:\\\\foo\\\\bar\\\".\\nCommon shell builtins and core utils available on Windows.\\n</cross_platform>\\n\\n<execution_steps>\\n1. Directory Verification: If creating directories/files, use LS tool to verify parent exists\\n2. Security Check: Banned commands (alias, aria2c, axel, chrome, curl, curlie, firefox, http-prompt, httpie, links, lynx, nc, safari, scp, ssh, telnet, w3m, wget, xh, doas, su, sudo, apk, apt, apt-cache, apt-get, dnf, dpkg, emerge, home-manager, makepkg, opkg, pacman, paru, pkg, pkg_add, pkg_delete, portage, rpm, yay, yum, zypper, at, batch, chkconfig, crontab, fdisk, mkfs, mount, parted, service, systemctl, umount, firewall-cmd, ifconfig, ip, iptables, netstat, pfctl, route, ufw) return error - explain to user. Safe read-only commands execute without prompts\\n3. Command Execution: Execute with proper quoting, capture output\\n4. Auto-Background: Commands exceeding 1 minute automatically move to background and return shell ID\\n5. Output Processing: Truncate if exceeds 30000 characters\\n6. Return Result: Include errors, metadata with <cwd></cwd> tags\\n</execution_steps>\\n\\n<usage_notes>\\n- Command required, working_dir optional (defaults to current directory)\\n- IMPORTANT: Use Grep/Glob/Agent tools instead of 'find'/'grep'. Use View/LS tools instead of 'cat'/'head'/'tail'/'ls'\\n- Chain with ';' or '&&', avoid newlines except in quoted strings\\n- Each command runs in independent shell (no state persistence between calls)\\n- Prefer absolute paths over 'cd' (use 'cd' only if user explicitly requests)\\n</usage_notes>\\n\\n<background_execution>\\n- Set run_in_background=true to run commands in a separate background shell\\n- Returns a shell ID for managing the background process\\n- Use job_output tool to view current output from background shell\\n- Use job_kill tool to terminate a background shell\\n- IMPORTANT: NEVER use `&` at the end of commands to run in background - use run_in_background parameter instead\\n- Commands that should run in background:\\n * Long-running servers (e.g., `npm start`, `python -m http.server`, `node server.js`)\\n * Watch/monitoring tasks (e.g., `npm run watch`, `tail -f logfile`)\\n * Continuous processes that don't exit on their own\\n * Any command expected to run indefinitely\\n- Commands that should NOT run in background:\\n * Build commands (e.g., `npm run build`, `go build`)\\n * Test suites (e.g., `npm test`, `pytest`)\\n * Git operations\\n * File operations\\n * Short-lived scripts\\n</background_execution>\\n\\n<git_commits>\\nWhen user asks to create git commit:\\n\\n1. Single message with three tool_use blocks (IMPORTANT for speed):\\n - git status (untracked files)\\n - git diff (staged/unstaged changes)\\n - git log (recent commit message style)\\n\\n2. Add relevant untracked files to staging. Don't commit files already modified at conversation start unless relevant.\\n\\n3. Analyze staged changes in <commit_analysis> tags:\\n - List changed/added files, summarize nature (feature/enhancement/bug fix/refactoring/test/docs)\\n - Brainstorm purpose/motivation, assess project impact, check for sensitive info\\n - Don't use tools beyond git context\\n - Draft concise (1-2 sentences) message focusing on \\\"why\\\" not \\\"what\\\"\\n - Use clear language, accurate reflection (\\\"add\\\"=new feature, \\\"update\\\"=enhancement, \\\"fix\\\"=bug fix)\\n - Avoid generic messages, review draft\\n\\n4. Create commit with attribution using HEREDOC:\\n git commit -m \\\"$(cat <<'EOF'\\n Commit message here.\\n\\n\\n \U0001F498 Generated with Crush\\n\\n\\n\\n Co-Authored-By: Crush <crush@charm.land>\\n\\n\\n EOF\\n )\\\"\\n\\n5. If pre-commit hook fails, retry ONCE. If fails again, hook preventing commit. If succeeds but files modified, MUST amend.\\n\\n6. Run git status to verify.\\n\\nNotes: Use \\\"git commit -am\\\" when possible, don't stage unrelated files, NEVER update config, don't push, no -i flags, no empty commits, return empty response.\\n</git_commits>\\n\\n<pull_requests>\\nUse gh command for ALL GitHub tasks. When user asks to create PR:\\n\\n1. Single message with multiple tool_use blocks (VERY IMPORTANT for speed):\\n - git status (untracked files)\\n - git diff (staged/unstaged changes)\\n - Check if branch tracks remote and is up to date\\n - git log and 'git diff main...HEAD' (full commit history from main divergence)\\n\\n2. Create new branch if needed\\n3. Commit changes if needed\\n4. Push to remote with -u flag if needed\\n\\n5. Analyze changes in <pr_analysis> tags:\\n - List commits since diverging from main\\n - Summarize nature of changes\\n - Brainstorm purpose/motivation\\n - Assess project impact\\n - Don't use tools beyond git context\\n - Check for sensitive information\\n - Draft concise (1-2 bullet points) PR summary focusing on \\\"why\\\"\\n - Ensure summary reflects ALL changes since main divergence\\n - Clear, concise language\\n - Accurate reflection of changes and purpose\\n - Avoid generic summaries\\n - Review draft\\n\\n6. Create PR with gh pr create using HEREDOC:\\n gh pr create --title \\\"title\\\" --body \\\"$(cat <<'EOF'\\n\\n ## Summary\\n\\n <1-3 bullet points>\\n\\n ## Test plan\\n\\n [Checklist of TODOs...]\\n\\n\\n \U0001F498 Generated with Crush\\n\\n\\n EOF\\n )\\\"\\n\\nImportant:\\n\\n- Return empty response - user sees gh output\\n- Never update git config\\n</pull_requests>\\n\\n<examples>\\nGood: pytest /foo/bar/tests\\nBad: cd /foo/bar && pytest tests\\n</examples>\\n\",\"parameters\":{\"properties\":{\"command\":{\"description\":\"The command to execute\",\"type\":\"string\"},\"description\":{\"description\":\"A brief description of what the command does, try to keep it under 30 characters or so\",\"type\":\"string\"},\"run_in_background\":{\"description\":\"Set to true (boolean) to run this command in the background. Use job_output to read the output later.\",\"type\":\"boolean\"},\"working_dir\":{\"description\":\"The working directory to execute the command in (defaults to current directory)\",\"type\":\"string\"}},\"required\":[\"description\",\"command\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"download\",\"strict\":false,\"description\":\"Downloads binary data from URL and saves to local file.\\n\\n<usage>\\n- Provide URL to download from\\n- Specify local file path where content should be saved\\n- Optional timeout for request\\n</usage>\\n\\n<features>\\n- Downloads any file type (binary or text)\\n- Auto-creates parent directories if missing\\n- Handles large files efficiently with streaming\\n- Sets reasonable timeouts to prevent hanging\\n- Validates input parameters before requests\\n</features>\\n\\n<limitations>\\n- Max file size: 100MB\\n- Only supports HTTP and HTTPS protocols\\n- Cannot handle authentication or cookies\\n- Some websites may block automated requests\\n- Will overwrite existing files without warning\\n</limitations>\\n\\n<tips>\\n- Use absolute paths or paths relative to working directory\\n- Set appropriate timeouts for large files or slow connections\\n</tips>\\n\",\"parameters\":{\"properties\":{\"file_path\":{\"description\":\"The local file path where the downloaded content should be saved\",\"type\":\"string\"},\"timeout\":{\"description\":\"Optional timeout in seconds (max 600)\",\"type\":\"integer\"},\"url\":{\"description\":\"The URL to download from\",\"type\":\"string\"}},\"required\":[\"url\",\"file_path\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"edit\",\"strict\":false,\"description\":\"Edits files by replacing text, creating new files, or deleting content. For moving/renaming use Bash 'mv'. For large edits use Write tool.\\n\\n<prerequisites>\\n1. Use View tool to understand file contents and context\\n2. For new files: Use LS tool to verify parent directory exists\\n3. **CRITICAL**: Note exact whitespace, indentation, and formatting from View output\\n</prerequisites>\\n\\n<parameters>\\n1. file_path: Absolute path to file (required)\\n2. old_string: Text to replace (must match exactly including whitespace/indentation)\\n3. new_string: Replacement text\\n4. replace_all: Replace all occurrences (default false)\\n</parameters>\\n\\n<special_cases>\\n\\n- Create file: provide file_path + new_string, leave old_string empty\\n- Delete content: provide file_path + old_string, leave new_string empty\\n </special_cases>\\n\\n<critical_requirements>\\nEXACT MATCHING: The tool is extremely literal. Text must match **EXACTLY**\\n\\n- Every space and tab character\\n- Every blank line\\n- Every newline character\\n- Indentation level (count the spaces/tabs)\\n- Comment spacing (`// comment` vs `//comment`)\\n- Brace positioning (`func() {` vs `func(){`)\\n\\nCommon failures:\\n\\n```\\nExpected: \\\" func foo() {\\\" (4 spaces)\\nProvided: \\\" func foo() {\\\" (2 spaces) ❌ FAILS\\n\\nExpected: \\\"}\\\\n\\\\nfunc bar() {\\\" (2 newlines)\\nProvided: \\\"}\\\\nfunc bar() {\\\" (1 newline) ❌ FAILS\\n\\nExpected: \\\"// Comment\\\" (space after //)\\nProvided: \\\"//Comment\\\" (no space) ❌ FAILS\\n```\\n\\nUNIQUENESS (when replace_all=false): old_string MUST uniquely identify target instance\\n\\n- Include 3-5 lines context BEFORE and AFTER change point\\n- Include exact whitespace, indentation, surrounding code\\n- If text appears multiple times, add more context to make it unique\\n\\nSINGLE INSTANCE: Tool changes ONE instance when replace_all=false\\n\\n- For multiple instances: set replace_all=true OR make separate calls with unique context\\n- Plan calls carefully to avoid conflicts\\n\\nVERIFICATION BEFORE USING: Before every edit\\n\\n1. View the file and locate exact target location\\n2. Check how many instances of target text exist\\n3. Copy the EXACT text including all whitespace\\n4. Verify you have enough context for unique identification\\n5. Double-check indentation matches (count spaces/tabs)\\n6. Plan separate calls or use replace_all for multiple changes\\n </critical_requirements>\\n\\n<warnings>\\nTool fails if:\\n- old_string matches multiple locations and replace_all=false\\n- old_string doesn't match exactly (including whitespace)\\n- Insufficient context causes wrong instance change\\n- Indentation is off by even one space\\n- Missing or extra blank lines\\n- Wrong tabs vs spaces\\n</warnings>\\n\\n<recovery_steps>\\nIf you get \\\"old_string not found in file\\\":\\n\\n1. **View the file again** at the specific location\\n2. **Copy more context** - include entire function if needed\\n3. **Check whitespace**:\\n - Count indentation spaces/tabs\\n - Look for blank lines\\n - Check for trailing spaces\\n4. **Verify character-by-character** that your old_string matches\\n5. **Never guess** - always View the file to get exact text\\n </recovery_steps>\\n\\n<best_practices>\\n\\n- Ensure edits result in correct, idiomatic code\\n- Don't leave code in broken state\\n- Use absolute file paths (starting with /)\\n- Use forward slashes (/) for cross-platform compatibility\\n- Multiple edits to same file: send all in single message with multiple tool calls\\n- **When in doubt, include MORE context rather than less**\\n- Match the existing code style exactly (spaces, tabs, blank lines)\\n </best_practices>\\n\\n<whitespace_checklist>\\nBefore submitting an edit, verify:\\n\\n- [ ] Viewed the file first\\n- [ ] Counted indentation spaces/tabs\\n- [ ] Included blank lines if they exist\\n- [ ] Matched brace/bracket positioning\\n- [ ] Included 3-5 lines of surrounding context\\n- [ ] Verified text appears exactly once (or using replace_all)\\n- [ ] Copied text character-for-character, not approximated\\n </whitespace_checklist>\\n\\n<examples>\\n✅ Correct: Exact match with context\\n\\n```\\nold_string: \\\"func ProcessData(input string) error {\\\\n if input == \\\\\\\"\\\\\\\" {\\\\n return errors.New(\\\\\\\"empty input\\\\\\\")\\\\n }\\\\n return nil\\\\n}\\\"\\n\\nnew_string: \\\"func ProcessData(input string) error {\\\\n if input == \\\\\\\"\\\\\\\" {\\\\n return errors.New(\\\\\\\"empty input\\\\\\\")\\\\n }\\\\n // New validation\\\\n if len(input) > 1000 {\\\\n return errors.New(\\\\\\\"input too long\\\\\\\")\\\\n }\\\\n return nil\\\\n}\\\"\\n```\\n\\n❌ Incorrect: Not enough context\\n\\n```\\nold_string: \\\"return nil\\\" // Appears many times!\\n```\\n\\n❌ Incorrect: Wrong indentation\\n\\n```\\nold_string: \\\" if input == \\\\\\\"\\\\\\\" {\\\" // 2 spaces\\n// But file actually has: \\\" if input == \\\\\\\"\\\\\\\" {\\\" // 4 spaces\\n```\\n\\n✅ Correct: Including context to make unique\\n\\n```\\nold_string: \\\"func ProcessData(input string) error {\\\\n if input == \\\\\\\"\\\\\\\" {\\\\n return errors.New(\\\\\\\"empty input\\\\\\\")\\\\n }\\\\n return nil\\\"\\n```\\n\\n</examples>\\n\\n<windows_notes>\\n\\n- Forward slashes work throughout (C:/path/file)\\n- File permissions handled automatically\\n- Line endings converted automatically (\\\\n ↔ \\\\r\\\\n)\\n </windows_notes>\\n\",\"parameters\":{\"properties\":{\"file_path\":{\"description\":\"The absolute path to the file to modify\",\"type\":\"string\"},\"new_string\":{\"description\":\"The text to replace it with\",\"type\":\"string\"},\"old_string\":{\"description\":\"The text to replace\",\"type\":\"string\"},\"replace_all\":{\"description\":\"Replace all occurrences of old_string (default false)\",\"type\":\"boolean\"}},\"required\":[\"file_path\",\"old_string\",\"new_string\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"multiedit\",\"strict\":false,\"description\":\"Makes multiple edits to a single file in one operation. Built on Edit tool for efficient multiple find-and-replace operations. Prefer over Edit tool for multiple edits to same file.\\n\\n<prerequisites>\\n1. Use View tool to understand file contents and context\\n2. Verify directory path is correct\\n3. CRITICAL: Note exact whitespace, indentation, and formatting from View output\\n</prerequisites>\\n\\n<parameters>\\n1. file_path: Absolute path to file (required)\\n2. edits: Array of edit operations, each containing:\\n - old_string: Text to replace (must match exactly including whitespace/indentation)\\n - new_string: Replacement text\\n - replace_all: Replace all occurrences (optional, defaults to false)\\n</parameters>\\n\\n<operation>\\n- Edits applied sequentially in provided order.\\n- Each edit operates on result of previous edit.\\n- PARTIAL SUCCESS: If some edits fail, successful edits are still applied. Failed edits are returned in the response.\\n- File is modified if at least one edit succeeds.\\n- Ideal for several changes to different parts of same file.\\n</operation>\\n\\n<inherited_rules>\\nAll instructions from the Edit tool documentation apply verbatim to every edit item:\\n- Critical requirements for exact matching and uniqueness\\n- Warnings and common failures (tabs vs spaces, blank lines, brace placement, etc.)\\n- Verification steps before using, recovery steps, best practices, and whitespace checklist\\nUse the same level of precision as Edit. Multiedit often fails due to formatting mismatches—double-check whitespace for every edit.\\n</inherited_rules>\\n\\n<critical_requirements>\\n1. Apply Edit tool rules to EACH edit (see edit.md).\\n2. Edits are applied in order; successful edits are kept even if later edits fail.\\n3. Plan sequence carefully: earlier edits change the file content that later edits must match.\\n4. Ensure each old_string is unique at its application time (after prior edits).\\n5. Check the response for failed edits and retry them if needed.\\n</critical_requirements>\\n\\n<verification_before_using>\\n1. View the file and copy exact text (including whitespace) for each target.\\n2. Check how many instances each old_string has BEFORE the sequence starts.\\n3. Dry-run mentally: after applying edit #N, will edit #N+1 still match? Adjust old_string/new_string accordingly.\\n4. Prefer fewer, larger context blocks over many tiny fragments that are easy to misalign.\\n5. If edits are independent, consider separate multiedit batches per logical region.\\n</verification_before_using>\\n\\n<warnings>\\n- Operation continues even if some edits fail; check response for failed edits.\\n- Earlier edits can invalidate later matches (added/removed spaces, lines, or reordered text).\\n- Mixed tabs/spaces, trailing spaces, or missing blank lines commonly cause failures.\\n- replace_all may affect unintended regions—use carefully or provide more context.\\n</warnings>\\n\\n<recovery_steps>\\nIf some edits fail:\\n1. Check the response metadata for the list of failed edits with their error messages.\\n2. View the file again to see the current state after successful edits.\\n3. Adjust the failed edits based on the new file content.\\n4. Retry the failed edits with corrected old_string values.\\n5. Consider breaking complex batches into smaller, independent operations.\\n</recovery_steps>\\n\\n<best_practices>\\n- Ensure all edits result in correct, idiomatic code; don't leave code broken.\\n- Use absolute file paths (starting with /).\\n- Use replace_all only when you're certain; otherwise provide unique context.\\n- Match existing style exactly (spaces, tabs, blank lines).\\n- Review failed edits in the response and retry with corrections.\\n</best_practices>\\n\\n<whitespace_checklist>\\nFor EACH edit, verify:\\n- [ ] Viewed the file first\\n- [ ] Counted indentation spaces/tabs\\n- [ ] Included blank lines if present\\n- [ ] Matched brace/bracket positioning\\n- [ ] Included 3–5 lines of surrounding context\\n- [ ] Verified text appears exactly once (or using replace_all deliberately)\\n- [ ] Copied text character-for-character, not approximated\\n</whitespace_checklist>\\n\\n<examples>\\n✅ Correct: Sequential edits where the second match accounts for the first change\\n\\n```\\nedits: [\\n {\\n old_string: \\\"func A() {\\\\n doOld()\\\\n}\\\",\\n new_string: \\\"func A() {\\\\n doNew()\\\\n}\\\",\\n },\\n {\\n // Uses context that still exists AFTER the first replacement\\n old_string: \\\"func B() {\\\\n callA()\\\\n}\\\",\\n new_string: \\\"func B() {\\\\n callA()\\\\n logChange()\\\\n}\\\",\\n },\\n]\\n```\\n\\n❌ Incorrect: Second old_string no longer matches due to whitespace change introduced by the first edit\\n\\n```\\nedits: [\\n {\\n old_string: \\\"func A() {\\\\n doOld()\\\\n}\\\",\\n new_string: \\\"func A() {\\\\n\\\\n doNew()\\\\n}\\\", // Added extra blank line\\n },\\n {\\n old_string: \\\"func A() {\\\\n doNew()\\\\n}\\\", // Missing the new blank line, will FAIL\\n new_string: \\\"func A() {\\\\n doNew()\\\\n logChange()\\\\n}\\\",\\n },\\n]\\n```\\n\\n✅ Correct: Handling partial success\\n\\n```\\n// If edit 2 fails, edit 1 is still applied\\n// Response will indicate:\\n// - edits_applied: 1\\n// - edits_failed: [{index: 2, error: \\\"...\\\", edit: {...}}]\\n// You can then retry edit 2 with corrected context\\n```\\n</examples>\\n\",\"parameters\":{\"properties\":{\"edits\":{\"description\":\"Array of edit operations to perform sequentially on the file\",\"items\":{\"properties\":{\"new_string\":{\"description\":\"The text to replace it with\",\"type\":\"string\"},\"old_string\":{\"description\":\"The text to replace\",\"type\":\"string\"},\"replace_all\":{\"description\":\"Replace all occurrences of old_string (default false).\",\"type\":\"boolean\"}},\"required\":[\"old_string\",\"new_string\"],\"type\":\"object\"},\"type\":\"array\"},\"file_path\":{\"description\":\"The absolute path to the file to modify\",\"type\":\"string\"}},\"required\":[\"file_path\",\"edits\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"fetch\",\"strict\":false,\"description\":\"Fetches raw content from URL and returns it in specified format without any AI processing.\\n\\n<when_to_use>\\nUse this tool when you need:\\n- Raw, unprocessed content from a URL\\n- Direct access to API responses or JSON data\\n- HTML/text/markdown content without interpretation\\n- Simple, fast content retrieval without analysis\\n- To save tokens by avoiding AI processing\\n\\nDO NOT use this tool when you need to:\\n- Extract specific information from a webpage (use agentic_fetch instead)\\n- Answer questions about web content (use agentic_fetch instead)\\n- Analyze or summarize web pages (use agentic_fetch instead)\\n</when_to_use>\\n\\n<usage>\\n- Provide URL to fetch content from\\n- Specify desired output format (text, markdown, or html)\\n- Optional timeout for request\\n</usage>\\n\\n<features>\\n- Supports three output formats: text, markdown, html\\n- Auto-handles HTTP redirects\\n- Fast and lightweight - no AI processing\\n- Sets reasonable timeouts to prevent hanging\\n- Validates input parameters before requests\\n</features>\\n\\n<limitations>\\n- Max response size: 5MB\\n- Only supports HTTP and HTTPS protocols\\n- Cannot handle authentication or cookies\\n- Some websites may block automated requests\\n- Returns raw content only - no analysis or extraction\\n</limitations>\\n\\n<tips>\\n- Use text format for plain text content or simple API responses\\n- Use markdown format for content that should be rendered with formatting\\n- Use html format when you need raw HTML structure\\n- Set appropriate timeouts for potentially slow websites\\n- If the user asks to analyze or extract from a page, use agentic_fetch instead\\n</tips>\\n\",\"parameters\":{\"properties\":{\"format\":{\"description\":\"The format to return the content in (text, markdown, or html)\",\"type\":\"string\"},\"timeout\":{\"description\":\"Optional timeout in seconds (max 120)\",\"type\":\"integer\"},\"url\":{\"description\":\"The URL to fetch content from\",\"type\":\"string\"}},\"required\":[\"url\",\"format\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"glob\",\"strict\":false,\"description\":\"Fast file pattern matching tool that finds files by name/pattern, returning paths sorted by modification time (newest first).\\n\\n<usage>\\n- Provide glob pattern to match against file paths\\n- Optional starting directory (defaults to current working directory)\\n- Results sorted with most recently modified files first\\n</usage>\\n\\n<pattern_syntax>\\n- '\\\\*' matches any sequence of non-separator characters\\n- '\\\\*\\\\*' matches any sequence including separators\\n- '?' matches any single non-separator character\\n- '[...]' matches any character in brackets\\n- '[!...]' matches any character not in brackets\\n</pattern_syntax>\\n\\n<examples>\\n- '*.js' - JavaScript files in current directory\\n- '**/*.js' - JavaScript files in any subdirectory\\n- 'src/**/*.{ts,tsx}' - TypeScript files in src directory\\n- '*.{html,css,js}' - HTML, CSS, and JS files\\n</examples>\\n\\n<limitations>\\n- Results limited to 100 files (newest first)\\n- Does not search file contents (use Grep for that)\\n- Hidden files (starting with '.') skipped\\n</limitations>\\n\\n<cross_platform>\\n- Path separators handled automatically (/ and \\\\ work)\\n- Uses ripgrep (rg) if available, otherwise Go implementation\\n- Patterns should use forward slashes (/) for compatibility\\n</cross_platform>\\n\\n<tips>\\n- Combine with Grep: find files with Glob, search contents with Grep\\n- For iterative exploration requiring multiple searches, consider Agent tool\\n- Check if results truncated and refine pattern if needed\\n</tips>\\n\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The directory to search in. Defaults to the current working directory.\",\"type\":\"string\"},\"pattern\":{\"description\":\"The glob pattern to match files against\",\"type\":\"string\"}},\"required\":[\"pattern\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"grep\",\"strict\":false,\"description\":\"Fast content search tool that finds files containing specific text/patterns, returning matching paths sorted by modification time (newest first).\\n\\n<usage>\\n- Provide regex pattern to search within file contents\\n- Set literal_text=true for exact text with special characters (recommended for non-regex users)\\n- Optional starting directory (defaults to current working directory)\\n- Optional include pattern to filter which files to search\\n- Results sorted with most recently modified files first\\n</usage>\\n\\n<regex_syntax>\\nWhen literal_text=false (supports standard regex):\\n\\n- 'function' searches for literal text \\\"function\\\"\\n- 'log\\\\..\\\\*Error' finds text starting with \\\"log.\\\" and ending with \\\"Error\\\"\\n- 'import\\\\s+.\\\\*\\\\s+from' finds import statements in JavaScript/TypeScript\\n</regex_syntax>\\n\\n<include_patterns>\\n- '\\\\*.js' - Only search JavaScript files\\n- '\\\\*.{ts,tsx}' - Only search TypeScript files\\n- '\\\\*.go' - Only search Go files\\n</include_patterns>\\n\\n<limitations>\\n- Results limited to 100 files (newest first)\\n- Performance depends on number of files searched\\n- Very large binary files may be skipped\\n- Hidden files (starting with '.') skipped\\n</limitations>\\n\\n<ignore_support>\\n- Respects .gitignore patterns to skip ignored files/directories\\n- Respects .crushignore patterns for additional ignore rules\\n- Both ignore files auto-detected in search root directory\\n</ignore_support>\\n\\n<cross_platform>\\n- Uses ripgrep (rg) if available for better performance\\n- Falls back to Go implementation if ripgrep unavailable\\n- File paths normalized automatically for compatibility\\n</cross_platform>\\n\\n<tips>\\n- For faster searches: use Glob to find relevant files first, then Grep\\n- For iterative exploration requiring multiple searches, consider Agent tool\\n- Check if results truncated and refine search pattern if needed\\n- Use literal_text=true for exact text with special characters (dots, parentheses, etc.)\\n</tips>\\n\",\"parameters\":{\"properties\":{\"include\":{\"description\":\"File pattern to include in the search (e.g. \\\"*.js\\\", \\\"*.{ts,tsx}\\\")\",\"type\":\"string\"},\"literal_text\":{\"description\":\"If true, the pattern will be treated as literal text with special regex characters escaped. Default is false.\",\"type\":\"boolean\"},\"path\":{\"description\":\"The directory to search in. Defaults to the current working directory.\",\"type\":\"string\"},\"pattern\":{\"description\":\"The regex pattern to search for in file contents\",\"type\":\"string\"}},\"required\":[\"pattern\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"ls\",\"strict\":false,\"description\":\"Shows files and subdirectories in tree structure for exploring project organization.\\n\\n<usage>\\n- Provide path to list (defaults to current working directory)\\n- Optional glob patterns to ignore\\n- Results displayed in tree structure\\n</usage>\\n\\n<features>\\n- Hierarchical view of files and directories\\n- Auto-skips hidden files/directories (starting with '.')\\n- Skips common system directories like __pycache__\\n- Can filter files matching specific patterns\\n</features>\\n\\n<limitations>\\n- Results limited to 1000 files\\n- Large directories truncated\\n- No file sizes or permissions shown\\n- Cannot recursively list all directories in large projects\\n</limitations>\\n\\n<cross_platform>\\n- Hidden file detection uses Unix convention (files starting with '.')\\n- Windows hidden files (with hidden attribute) not auto-skipped\\n- Common Windows directories (System32, Program Files) not in default ignore\\n- Path separators handled automatically (/ and \\\\ work)\\n</cross_platform>\\n\\n<tips>\\n- Use Glob for finding files by name patterns instead of browsing\\n- Use Grep for searching file contents\\n- Combine with other tools for effective exploration\\n</tips>\\n\",\"parameters\":{\"properties\":{\"depth\":{\"description\":\"The maximum depth to traverse\",\"type\":\"integer\"},\"ignore\":{\"description\":\"List of glob patterns to ignore\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"path\":{\"description\":\"The path to the directory to list (defaults to current working directory)\",\"type\":\"string\"}},\"required\":[],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"sourcegraph\",\"strict\":false,\"description\":\"Search code across public repositories using Sourcegraph's GraphQL API.\\n\\n<usage>\\n- Provide search query using Sourcegraph syntax\\n- Optional result count (default: 10, max: 20)\\n- Optional timeout for request\\n</usage>\\n\\n<basic_syntax>\\n- \\\"fmt.Println\\\" - exact matches\\n- \\\"file:.go fmt.Println\\\" - limit to Go files\\n- \\\"repo:^github\\\\.com/golang/go$ fmt.Println\\\" - specific repos\\n- \\\"lang:go fmt.Println\\\" - limit to Go code\\n- \\\"fmt.Println AND log.Fatal\\\" - combined terms\\n- \\\"fmt\\\\.(Print|Printf|Println)\\\" - regex patterns\\n- \\\"\\\\\\\"exact phrase\\\\\\\"\\\" - exact phrase matching\\n- \\\"-file:test\\\" or \\\"-repo:forks\\\" - exclude matches\\n</basic_syntax>\\n\\n<key_filters>\\nRepository: repo:name, repo:^exact$, repo:org/repo@branch, -repo:exclude, fork:yes, archived:yes, visibility:public\\nFile: file:\\\\.js$, file:internal/, -file:test, file:has.content(text)\\nContent: content:\\\"exact\\\", -content:\\\"unwanted\\\", case:yes\\nType: type:symbol, type:file, type:path, type:diff, type:commit\\nTime: after:\\\"1 month ago\\\", before:\\\"2023-01-01\\\", author:name, message:\\\"fix\\\"\\nResult: select:repo, select:file, select:content, count:100, timeout:30s\\n</key_filters>\\n\\n<examples>\\n- \\\"file:.go context.WithTimeout\\\" - Go code using context.WithTimeout\\n- \\\"lang:typescript useState type:symbol\\\" - TypeScript React useState hooks\\n- \\\"repo:^github\\\\.com/kubernetes/kubernetes$ pod list type:file\\\" - Kubernetes pod files\\n- \\\"file:Dockerfile (alpine OR ubuntu) -content:alpine:latest\\\" - Dockerfiles with base images\\n</examples>\\n\\n<boolean_operators>\\n- \\\"term1 AND term2\\\" - both terms\\n- \\\"term1 OR term2\\\" - either term\\n- \\\"term1 NOT term2\\\" - term1 but not term2\\n- \\\"term1 and (term2 or term3)\\\" - grouping with parentheses\\n</boolean_operators>\\n\\n<limitations>\\n- Only searches public repositories\\n- Rate limits may apply\\n- Complex queries take longer\\n- Max 20 results per query\\n</limitations>\\n\\n<tips>\\n- Use specific file extensions to narrow results\\n- Add repo: filters for targeted searches\\n- Use type:symbol for function/method definitions\\n- Use type:file to find relevant files\\n</tips>\\n\",\"parameters\":{\"properties\":{\"context_window\":{\"description\":\"The context around the match to return (default: 10 lines)\",\"type\":\"integer\"},\"count\":{\"description\":\"Optional number of results to return (default: 10, max: 20)\",\"type\":\"integer\"},\"query\":{\"description\":\"The Sourcegraph search query\",\"type\":\"string\"},\"timeout\":{\"description\":\"Optional timeout in seconds (max 120)\",\"type\":\"integer\"}},\"required\":[\"query\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"view\",\"strict\":false,\"description\":\"Reads and displays file contents with line numbers for examining code, logs, or text data.\\n\\n<usage>\\n- Provide file path to read\\n- Optional offset: start reading from specific line (0-based)\\n- Optional limit: control lines read (default 2000)\\n- Don't use for directories (use LS tool instead)\\n- Supports image files (PNG, JPEG, GIF, BMP, SVG, WebP)\\n</usage>\\n\\n<features>\\n- Displays contents with line numbers\\n- Can read from any file position using offset\\n- Handles large files by limiting lines read\\n- Auto-truncates very long lines for display\\n- Suggests similar filenames when file not found\\n- Renders image files directly in terminal\\n</features>\\n\\n<limitations>\\n- Max file size: 5MB\\n- Default limit: 2000 lines\\n- Lines >2000 chars truncated\\n- Binary files (except images) cannot be displayed\\n</limitations>\\n\\n<cross_platform>\\n- Handles Windows (CRLF) and Unix (LF) line endings\\n- Works with forward slashes (/) and backslashes (\\\\)\\n- Auto-detects text encoding for common formats\\n</cross_platform>\\n\\n<tips>\\n- Use with Glob to find files first\\n- For code exploration: Grep to find relevant files, then View to examine\\n- For large files: use offset parameter for specific sections\\n- View tool automatically detects and renders image files\\n</tips>\\n\",\"parameters\":{\"properties\":{\"file_path\":{\"description\":\"The path to the file to read\",\"type\":\"string\"},\"limit\":{\"description\":\"The number of lines to read (defaults to 2000)\",\"type\":\"integer\"},\"offset\":{\"description\":\"The line number to start reading from (0-based)\",\"type\":\"integer\"}},\"required\":[\"file_path\"],\"type\":\"object\"}},\"type\":\"function\"},{\"function\":{\"name\":\"write\",\"strict\":false,\"description\":\"Creates or updates files in filesystem for saving/modifying text content.\\n\\n<usage>\\n- Provide file path to write\\n- Include content to write to file\\n- Tool creates necessary parent directories automatically\\n</usage>\\n\\n<features>\\n- Creates new files or overwrites existing ones\\n- Auto-creates parent directories if missing\\n- Checks if file modified since last read for safety\\n- Avoids unnecessary writes when content unchanged\\n</features>\\n\\n<limitations>\\n- Read file before writing to avoid conflicts\\n- Cannot append (rewrites entire file)\\n</limitations>\\n\\n<cross_platform>\\n- Use forward slashes (/) for compatibility\\n</cross_platform>\\n\\n<tips>\\n- Use View tool first to examine existing files before modifying\\n- Use LS tool to verify location when creating new files\\n- Combine with Glob/Grep to find and modify multiple files\\n- Include descriptive comments when changing existing code\\n</tips>\\n\",\"parameters\":{\"properties\":{\"content\":{\"description\":\"The content to write to the file\",\"type\":\"string\"},\"file_path\":{\"description\":\"The path to the file to write\",\"type\":\"string\"}},\"required\":[\"file_path\",\"content\"],\"type\":\"object\"}},\"type\":\"function\"}],\"usage\":{\"include\":true},\"stream\":true}"
268 headers:
269 Accept:
270 - application/json
271 Content-Type:
272 - application/json
273 User-Agent:
274 - OpenAI/Go 2.7.1
275 url: https://openrouter.ai/api/v1/chat/completions
276 method: POST
277 response:
278 proto: HTTP/2.0
279 proto_major: 2
280 proto_minor: 0
281 content_length: -1
282 body: |+
283 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"The","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
284
285 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" first","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
286
287 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" search","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
288
289 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" successfully","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
290
291 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" found","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
292
293 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" Go","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
294
295 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" repositories","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
296
297 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" containing","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
298
299 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" '","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
300
301 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"func","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
302
303 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" main","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
304
305 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"'.","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
306
307 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" Most","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
308
309 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" examples","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
310
311 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" show","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
312
313 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" simple","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
314
315 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" Go","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
316
317 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" programs","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
318
319 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" from","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
320
321 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" educational","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
322
323 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" repositories","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
324
325 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" (","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
326
327 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"particularly","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
328
329 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" from","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
330
331 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" a","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
332
333 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" \"","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
334
335 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"deep","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
336
337 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"_go","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
338
339 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"\"","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
340
341 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" course","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
342
343 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" repository","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
344
345 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"),","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
346
347 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" demonstrating","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
348
349 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":":\n\n","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
350
351 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"-","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
352
353 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" Basic","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
354
355 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" main","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
356
357 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" function","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
358
359 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" structure","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
360
361 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"\n-","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
362
363 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" De","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
364
365 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"fer","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
366
367 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" statements","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
368
369 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" with","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
370
371 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" functions","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
372
373 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"\n-","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
374
375 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" High","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
376
377 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"-order","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
378
379 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" functions","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
380
381 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"\n-","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
382
383 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" Function","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
384
385 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" composition","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
386
387 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"\n-","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
388
389 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" Context","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
390
391 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" handling","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
392
393 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"\n\nThe","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
394
395 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" second","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
396
397 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" search","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
398
399 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" appears","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
400
401 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" to","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
402
403 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" have","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
404
405 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" had","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
406
407 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" a","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
408
409 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" syntax","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
410
411 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" error","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
412
413 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" in","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
414
415 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" the","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
416
417 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" query","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
418
419 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" format","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
420
421 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" and","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
422
423 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" returned","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
424
425 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" results","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
426
427 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" from","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
428
429 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" Python","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
430
431 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"/R","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
432
433 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"ust","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
434
435 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" repositories","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
436
437 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" instead","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
438
439 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" of","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
440
441 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" Go","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
442
443 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" code","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
444
445 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":".\n\n","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
446
447 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"The","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
448
449 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" Source","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
450
451 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"graph","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
452
453 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" API","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
454
455 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" found","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
456
457 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" 30","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
458
459 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" matches","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
460
461 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" for","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
462
463 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" '","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
464
465 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"func","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
466
467 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" main","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
468
469 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"'","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
470
471 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" in","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
472
473 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" Go","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
474
475 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" repositories","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
476
477 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":",","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
478
479 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" primarily","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
480
481 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" showcasing","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
482
483 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" programming","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
484
485 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" concepts","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
486
487 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" and","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
488
489 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" patterns","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
490
491 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" in","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
492
493 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" Go","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
494
495 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" with","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
496
497 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" main","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
498
499 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"()","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
500
501 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" functions","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
502
503 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" as","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
504
505 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" entry","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
506
507 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":" points","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
508
509 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":".","role":"assistant"},"finish_reason":null,"native_finish_reason":null}]}
510
511 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[{"index":0,"delta":{"content":"","role":"assistant"},"finish_reason":"stop","native_finish_reason":"stop"}]}
512
513 data: {"id":"gen-1773004345-ptk8hqiIQwRrVg1H7N68","object":"chat.completion.chunk","created":1773004345,"model":"moonshotai/kimi-k2-0905","provider":"DeepInfra","choices":[],"usage":{"prompt_tokens":20624,"completion_tokens":120,"total_tokens":20744,"cost":0.0048576,"is_byok":false,"prompt_tokens_details":{"cached_tokens":14528,"cache_write_tokens":0,"audio_tokens":0,"video_tokens":0},"cost_details":{"upstream_inference_cost":0.0048576,"upstream_inference_prompt_cost":0.0046176,"upstream_inference_completions_cost":0.00024},"completion_tokens_details":{"reasoning_tokens":0,"image_tokens":0,"audio_tokens":0}}}
514
515 data: [DONE]
516
517 headers:
518 Content-Type:
519 - text/event-stream
520 status: 200 OK
521 code: 200
522 duration: 1.019954041s