From 5932f40bd215eb3448cce58d6793b82864dd4fc1 Mon Sep 17 00:00:00 2001 From: Nathan Hangen Date: Wed, 28 Jan 2026 22:26:10 -0500 Subject: [PATCH] chore: granular lint and format fix --- comments_3647.txt | 47 +++++++++ comments_3648.txt | 47 +++++++++ feedback_3647.txt | 20 ++++ feedback_3648.txt | 29 +++++ pr3647.json | Bin 0 -> 2964 bytes pr3647_comments.json | Bin 0 -> 59500 bytes pr3648.json | Bin 0 -> 3970 bytes pr3648_comments.json | Bin 0 -> 47552 bytes pr3648_latest_comments.json | Bin 0 -> 47554 bytes src/agents/system-prompt.ts | 205 ++++++++++++++++++------------------ system-prompt.original.ts | Bin 0 -> 51122 bytes 11 files changed, 246 insertions(+), 102 deletions(-) create mode 100644 comments_3647.txt create mode 100644 comments_3648.txt create mode 100644 feedback_3647.txt create mode 100644 feedback_3648.txt create mode 100644 pr3647.json create mode 100644 pr3647_comments.json create mode 100644 pr3648.json create mode 100644 pr3648_comments.json create mode 100644 pr3648_latest_comments.json create mode 100644 system-prompt.original.ts diff --git a/comments_3647.txt b/comments_3647.txt new file mode 100644 index 000000000..8b5f8fcd2 --- /dev/null +++ b/comments_3647.txt @@ -0,0 +1,47 @@ +FILE: src/agents/session-transcript-repair.ts +LINE: 62 +BODY: The comment on line 60 is questioning rather than explanatory. Comments with questions like "Deep clone to avoid mutating the input unless necessary?" and "Actually, we can mutate in place effectively or clone messages that need change" suggest uncertainty or incomplete decision-making. The implementation does create a new array and new message objects when changes are detected (lines 63, 107-110), so the comment should clearly state the approach taken: "Creates new message objects only when sanitization is needed; otherwise returns the original messages to avoid unnecessary copying." +```suggestion + // Creates new message objects only when sanitization is needed; otherwise + // returns the original messages to avoid unnecessary copying, while guarding + // against corrupt JSON in tool arguments that could break the session. +``` +--- +FILE: src/agents/session-transcript-repair.ts +LINE: 86 +BODY: The function validates and discards valid JSON strings but doesn't parse them. When `input` is a string containing valid JSON (line 85), the code simply pushes the block unchanged. However, if `input` should always be an object (not a string), then valid JSON strings should also be parsed and converted to objects for consistency. Clarify the expected behavior: should valid JSON strings be preserved as-is, or should they also be parsed into objects? The current behavior creates inconsistency where some inputs are objects and some are JSON strings. +```suggestion + const parsedInput = JSON.parse((block as any).input); + nextContent.push({ + ...block, + input: parsedInput, + }); + msgChanged = true; +``` +--- +FILE: src/agents/session-transcript-repair.ts +LINE: 118 +BODY: The function doesn't return any report or metadata about what was sanitized, unlike `repairToolUseResultPairing` which returns a `ToolUseRepairReport` with details about changes made. Consider returning a report object that includes information such as the number of sanitized blocks and which tool types were affected. This would help with debugging, monitoring, and understanding the extent of data corruption in sessions. Alternatively, add inline logging to track sanitization events. +--- +FILE: src/agents/session-transcript-repair.ts +LINE: 118 +BODY: The `sanitizeToolUseArgs` function lacks test coverage. The existing test file only tests `sanitizeToolUseResultPairing`, but does not directly test the new `sanitizeToolUseArgs` function. Add tests that verify: +1. Valid JSON strings in `input` fields are preserved +2. Invalid JSON strings in `input` fields are replaced with `{}` +3. Object values in `input` fields are preserved +4. The `_sanitized` and `_originalInput` metadata fields are correctly set when sanitization occurs +5. Messages without tool blocks are left unchanged +--- +FILE: src/agents/session-transcript-repair.ts +LINE: 97 +BODY: Silent data loss occurs when malformed JSON is replaced with an empty object. When the sanitization logic detects and replaces invalid JSON in tool arguments, it stores the original input in `_originalInput` but doesn't log this potentially important information. Consider adding a warning log similar to patterns found elsewhere in the codebase (e.g., in `compaction.ts`, `model-catalog.ts`) to aid debugging when sessions are repaired. The log should include the tool name and a sample of the malformed input to help trace the root cause of the corruption. +--- +FILE: src/agents/session-transcript-repair.ts +LINE: 100 +BODY: The function only sanitizes the `input` field for tool use blocks, but the existing tests use `arguments` as the field name (see lines 11-12, 38, 65 in session-transcript-repair.test.ts). This suggests there may be inconsistency in the field naming across different tool block types. Verify whether tool blocks can use both `input` and `arguments` field names, and if so, ensure the sanitization logic handles both. If they are mutually exclusive based on the block type, add a comment explaining this distinction. +--- +FILE: src/agents/session-transcript-repair.ts +LINE: 94 +BODY: Using `(block as any).input` bypasses TypeScript's type checking. The code would be more maintainable and safer with proper type guards or typed access. Consider defining a proper type for tool blocks or using a type guard function to check for the presence of the `input` field before accessing it. This approach would make the code more self-documenting and catch potential issues at compile time. +--- + diff --git a/comments_3648.txt b/comments_3648.txt new file mode 100644 index 000000000..b469c65b4 --- /dev/null +++ b/comments_3648.txt @@ -0,0 +1,47 @@ +FILE: src/agents/system-prompt.ts +LINE: 412 +BODY: The Windows shell guidance feature lacks test coverage. Consider adding a test case in `system-prompt.test.ts` to verify that the Windows-specific guidance is included when `runtimeInfo.os` contains "windows" and excluded otherwise. This would ensure the feature works as expected and prevent regressions. + +For example, you could add a test like: +- Test that when runtimeInfo.os includes "Windows_NT", the prompt contains "## Windows Shell Guidance" +- Test that when runtimeInfo.os is "Darwin" or "Linux", this section is not included +--- +FILE: src/agents/system-prompt.ts +LINE: 100 +BODY: This PR includes extensive indentation/formatting changes throughout the file that are not mentioned in the PR description. While these changes appear to be consistent reformatting (switching from multi-line template literals to array-based formatting), they make it harder to review the actual functional change (the Windows guidance addition). Consider: + +1. Splitting formatting changes into a separate commit/PR, OR +2. Explicitly mentioning these formatting changes in the PR description + +This follows best practices for keeping functional changes separate from style/formatting changes for easier code review and git history. +--- +FILE: src/agents/system-prompt.ts +LINE: 407 +BODY: The Windows guidance warns against using Unix commands like `grep`, but the system prompt (lines 340-342) also lists `grep`, `find`, and `ls` as Pi's standard tools. This could be confusing because: + +1. Pi provides `grep`, `find`, and `ls` as built-in tools that work cross-platform +2. The Windows guidance seems to warn against using these names in shell commands via the `exec` tool + +Consider clarifying this distinction in the Windows guidance. For example: "- Do NOT use Unix commands like `grep`, `sed`, `awk`, `head`, `tail` in exec/shell commands unless you are sure they are installed (Pi's built-in grep/find/ls tools work fine)." + +This makes it clear that the warning is specifically about shell commands, not Pi's built-in tools. +```suggestion + "- Do NOT use Unix commands like `grep`, `sed`, `awk`, `head`, `tail` in exec/shell (PowerShell) commands unless you are sure they are installed. Pi's built-in tools named `grep`, `find`, and `ls` are safe to use.", +``` +--- +FILE: .github/PULL_REQUEST_TEMPLATE.md +LINE: 315 +BODY: The PR includes changes to `.github/PULL_REQUEST_TEMPLATE.md` which is unrelated to adding Windows PowerShell support. The diff shows the entire file (315 lines) as new additions, which suggests either: + +1. The file was regenerated/reformatted +2. Line ending changes (CRLF ↔ LF) +3. The file was accidentally included in this PR + +Since this is unrelated to the stated PR purpose ("add windows powershell support to system prompt"), consider: +- Removing this file from the PR if it was accidentally included +- If intentional, explain the reason in the PR description +- If it's a line ending change, consider using `.gitattributes` to enforce consistent line endings + +Including unrelated changes makes code review more difficult and complicates the git history. +--- + diff --git a/feedback_3647.txt b/feedback_3647.txt new file mode 100644 index 000000000..888691f36 --- /dev/null +++ b/feedback_3647.txt @@ -0,0 +1,20 @@ +--- PR 3647 -- +REVIEWER: copilot-pull-request-reviewer +BODY: ## Pull request overview + +This PR implements sanitization for tool arguments in session history to prevent crashes caused by malformed JSON in tool input fields. When invalid JSON is detected in tool use blocks, it is replaced with an empty object `{}` to prevent `InternalError.Algo.InvalidParameter` errors that would otherwise crash the entire session. + +**Changes:** +- Added `sanitizeToolUseArgs` function to detect and repair malformed JSON in tool input arguments +- Integrated sanitization into the `sanitizeToolUseResultPairing` pipeline to ensure it runs before tool result pairing repair +- Preserved original malformed input in `_originalInput` metadata field for debugging + + + + + +--- + +💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started. + + diff --git a/feedback_3648.txt b/feedback_3648.txt new file mode 100644 index 000000000..19a806574 --- /dev/null +++ b/feedback_3648.txt @@ -0,0 +1,29 @@ +--- PR 3648 -- +REVIEWER: copilot-pull-request-reviewer +BODY: ## Pull request overview + +This PR adds Windows-specific shell guidance to the agent's system prompt to help it use PowerShell syntax and commands when running on Windows. The implementation detects Windows via the runtime OS information and injects appropriate guidance about PowerShell syntax, environment variables, and command alternatives. + +**Changes:** +- Added conditional Windows Shell Guidance section to system prompt when running on Windows +- Reformatted multiple sections of system-prompt.ts from template literals to array-based formatting +- Modified .github/PULL_REQUEST_TEMPLATE.md (appears unrelated to main feature) + +### Reviewed changes + +Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments. + +| File | Description | +| ---- | ----------- | +| src/agents/system-prompt.ts | Added Windows PowerShell guidance section (lines 402-412) with conditional logic based on OS detection; includes extensive indentation/formatting changes throughout the file | +| .github/PULL_REQUEST_TEMPLATE.md | Entire file appears as new additions (315 lines), likely due to formatting or line ending changes; unrelated to Windows PowerShell feature | + + + + + +--- + +💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started. + + diff --git a/pr3647.json b/pr3647.json new file mode 100644 index 0000000000000000000000000000000000000000..9ac54f4e94b4367a68693731ad75faee5dab4df2 GIT binary patch literal 2964 zcmd6p+in|G6owbKNW89Xqrmt`mEW#8dmqzP5qwGCHz7yN^_5JNCW3MOyY!TQYNo$HMhxYszSh z#hK4UJPXE}udHhebf#QgkLFiKIk9MEJ-Xa2UfuB0N4CV$5Q`~V6TTZyuZZ`R9pG27 z4Oq$Sw>pYDcE=L33*X5#-wCo8#8Ir!`3bAKkI8O=N9i8%oPg|t=<_v%6V_8?Cmzq+ zwYU-+VYxuB;yp(%VYL9C<%Yh{k`*CQ);T4$XK5DX5jGOM2ToDn1SASlDcraV$Y^M#gU;` zaS#0|iR*qMO2sH{3}IPGK1fx2=P-YM%5_oc6&AtB5YW>t~O^PFSrm)d7yr}oaS zc)kz0Q+tjD#aQqbLI->mj(5-cjK_TUT&m6V5J@2}979(gWFs_{yY__GnXrrI&N<~T z{;Ns_v&t@KuB~2ZX)Y=|K~AGhR`i^eV&=zOPu$OpI92<7pVL|wy*?FC4dnTh)pdsE z@H+VTt=sS8Ys{B284>Tys}_5!L2tdDfxRq8eNyrf%l|viZtjXEkETXrJP6asXfvO- z69mh|%l^pGQ)j5y<&lfHI(9tNyB0`HdCzz^c&JJxSVfhBvxQ?P1`Lplz29iW z?w7Q*h-$|7rU#OwDbE1f7qW`edxB&JhzcOLZV|^co#|) zwzXGoj)niF&kMI1Up>BhmbyO5_!7bToBg)j}Q< z5ME-b=_Q(L&k*`2+*ZpoELB9NuC&FKVQt80vtB*s6zLW=RZWfBY&34OnQ-b*K4Wmd zE+@Wbt5rp~z>@x?LPCE}>9n@GE_)j?-5QbZ2CuGrjN1JldGUhWRY&c1oy#tHM>o_z zLOn-WHS?4@+zcOZa a`PxQLC*vKY?xNM<%yGqe`^rAD5A7d^rWcj~ literal 0 HcmV?d00001 diff --git a/pr3647_comments.json b/pr3647_comments.json new file mode 100644 index 0000000000000000000000000000000000000000..641bd66753566daaf1207b42779cef2061573da5 GIT binary patch literal 59500 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 literal 0 HcmV?d00001 diff --git a/pr3648.json b/pr3648.json new file mode 100644 index 0000000000000000000000000000000000000000..93b9c8da9b01ea96c678ed6d2f9c2236c0ce3e86 GIT binary patch literal 3970 zcmd6q-EtH~7>3(ZtGtJ)a3EOhCO`;30v3kINk9xxR;g5KcXpF3*-YZ@21MZ|yeRL+ zTTq{;dpa|lT@=d`Yif6xOT%K5)Z=H;hWG88;o|s&2R&$S-6UZ3TgHA!YMNcSe(T5 z>KZfJN24;g`RUIIW9Mg~!}BT6W1jTpM@B<@@lD&iVbu6;!ODGPr)VnC*kjd*=WOXQ z{yq*{*wnW^ZwBE_?Zt&~ArwTHY!~Nj7s$TCkI7kfen6|gXGAx`qHA~f@1b)L$KNtv z@q8R}*wF`ANp?ab>bV%~eq=X@mV)>kAKRQ74KQITEI zc0>%h`b|9g`V#qUrANk6?)*=PQQKlQdJ!+8`9m^z87X75m#j<`y)?f@(yMLtslC`% zdU?j3AG6A8Rdqz-a2mQ1eIoEPu1#{R1~D?FtDN&)2hI1%t=Y}>w6Y>1b%y#Ev)x9< z!v$oDBQuyZWTgHbBL5v~vgbS4X;;%c7{yWSQth9_4BAO;kHpV0E1hq;L}qEaq>KN` z?bUNeVK1psAnw0_RLA-{d@TGy|6UsGS?SRUb#dAIkIbeC#bhXbPN zhgJIWdD!OKg-5pF)#v;_rF(YyZG}g?-=>y6ckxqu7qKmVhukO8KRZ&E%rPjHe6}C- zNH3M2VO7aXXE>4pFYw;1=RF{!rj0Hm^0!Gu4R0sLoL_epZO7OV^{F1tlr5~LtjYc2 zR*uj^bCNhU?*)r|ockrQVyaQb$9l9fzsoiK@|L$>pMXB^HFoJvSPxgY zU&7{V-kSBq_{$g~@7g6YZOkXuPwd;~@Wc(DBdy&M`=?+wRe8uBW34JOG6HMXK`Gy- zJt)^;b!kt{V<`3I0T~x-`$Um3m-h;LE>}BO=)ZTLwc3jQ%JIg~*g4;qazufw=PEf} zMs7IRcNfDos&SpCrc#&U&fxfvm1FqEebVz#?&@WXW3NqGdeTm$y|hoa`)?Yo(EC~A z!|*rHD7g=D^|;}_JsTb_TVMzO%j zC2<>%T$p-nS#)J29BF(M&aig(VYdk++X57eKnk*SFSM=lellUb#>lb_fDOW z&K$1JTm1jxVw+4_M|V|uQT9pafrLXVop71<&WwaENcS6QO2+$C#LOj$``pua+ts*> zY>?qKn5)B1atrLQaoy&3i+?4)t2Nmf?Ok9qqA8uU2JmR&LpAT=v8SzJ^gw*|SebW( zhpdy|#ZvprHN~Ni$-7Oy2p(~5@x|wv=|SyB{-QA=CH*2jCcgZA+r#rKXxYH~4g9~s xckOj%N}kr4E1ByvvmX7t$$gEdE78XR_iJbxAa@<90q<7AJFXY}J_#R(zW}?L#-jiL literal 0 HcmV?d00001 diff --git a/pr3648_comments.json b/pr3648_comments.json new file mode 100644 index 0000000000000000000000000000000000000000..02b6ca39808197b4c5130efed138eaf822638f87 GIT binary patch literal 47552 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 YZ{McI@a|!rIj`#z_4594^+(nJ17=6fJpcdz literal 0 HcmV?d00001 diff --git a/pr3648_latest_comments.json b/pr3648_latest_comments.json new file mode 100644 index 0000000000000000000000000000000000000000..0ad68c5d1408dbd5204ad4e9652d6935a2f5bcdd GIT binary patch literal 47554 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 literal 0 HcmV?d00001 diff --git a/src/agents/system-prompt.ts b/src/agents/system-prompt.ts index a3c973b43..8264f934a 100644 --- a/src/agents/system-prompt.ts +++ b/src/agents/system-prompt.ts @@ -83,21 +83,21 @@ function buildMessagingSection(params: { "- Never use exec/curl for provider messaging; Moltbot handles all routing internally.", params.availableTools.has("message") ? [ - "", - "### message tool", - "- Use `message` for proactive sends + channel actions (polls, reactions, etc.).", - "- For `action=send`, include `to` and `message`.", - `- If multiple channels are configured, pass \`channel\` (${params.messageChannelOptions}).`, - `- If you use \`message\` (\`action=send\`) to deliver your user-visible reply, respond with ONLY: ${SILENT_REPLY_TOKEN} (avoid duplicate replies).`, - params.inlineButtonsEnabled - ? "- Inline buttons supported. Use `action=send` with `buttons=[[{text,callback_data}]]` (callback_data routes back as a user message)." - : params.runtimeChannel - ? `- Inline buttons not enabled for ${params.runtimeChannel}. If you need them, ask to set ${params.runtimeChannel}.capabilities.inlineButtons ("dm"|"group"|"all"|"allowlist").` - : "", - ...(params.messageToolHints ?? []), - ] - .filter(Boolean) - .join("\n") + "", + "### message tool", + "- Use `message` for proactive sends + channel actions (polls, reactions, etc.).", + "- For `action=send`, include `to` and `message`.", + `- If multiple channels are configured, pass \`channel\` (${params.messageChannelOptions}).`, + `- If you use \`message\` (\`action=send\`) to deliver your user-visible reply, respond with ONLY: ${SILENT_REPLY_TOKEN} (avoid duplicate replies).`, + params.inlineButtonsEnabled + ? "- Inline buttons supported. Use `action=send` with `buttons=[[{text,callback_data}]]` (callback_data routes back as a user message)." + : params.runtimeChannel + ? `- Inline buttons not enabled for ${params.runtimeChannel}. If you need them, ask to set ${params.runtimeChannel}.capabilities.inlineButtons ("dm"|"group"|"all"|"allowlist").` + : "", + ...(params.messageToolHints ?? []), + ] + .filter(Boolean) + .join("\n") : "", "", ]; @@ -282,15 +282,15 @@ export function buildAgentSystemPrompt(params: { : undefined; const reasoningHint = params.reasoningTagHint ? [ - "ALL internal reasoning MUST be inside ....", - "Do not output any analysis outside .", - "Format every reply as ... then ..., with no other text.", - "Only the final user-visible reply may appear inside .", - "Only text inside is shown to the user; everything else is discarded and never seen by the user.", - "Example:", - "Short internal reasoning.", - "Hey there! What would you like to do next?", - ].join(" ") + "ALL internal reasoning MUST be inside ....", + "Do not output any analysis outside .", + "Format every reply as ... then ..., with no other text.", + "Only the final user-visible reply may appear inside .", + "Only text inside is shown to the user; everything else is discarded and never seen by the user.", + "Example:", + "Short internal reasoning.", + "Hey there! What would you like to do next?", + ].join(" ") : undefined; const reasoningLevel = params.reasoningLevel ?? "off"; const userTimezone = params.userTimezone?.trim(); @@ -336,21 +336,21 @@ export function buildAgentSystemPrompt(params: { toolLines.length > 0 ? toolLines.join("\n") : [ - "Pi lists the standard tools above. This runtime enables:", - "- grep: search file contents for patterns", - "- find: find files by glob pattern", - "- ls: list directory contents", - "- apply_patch: apply multi-file patches", - `- ${execToolName}: run shell commands (supports background via yieldMs/background)`, - `- ${processToolName}: manage background exec sessions`, - "- browser: control clawd's dedicated browser", - "- canvas: present/eval/snapshot the Canvas", - "- nodes: list/describe/notify/camera/screen on paired nodes", - "- cron: manage cron jobs and wake events (use for reminders; when scheduling a reminder, write the systemEvent text as something that will read like a reminder when it fires, and mention that it is a reminder depending on the time gap between setting and firing; include recent context in reminder text if appropriate)", - "- sessions_list: list sessions", - "- sessions_history: fetch session history", - "- sessions_send: send to another session", - ].join("\n"), + "Pi lists the standard tools above. This runtime enables:", + "- grep: search file contents for patterns", + "- find: find files by glob pattern", + "- ls: list directory contents", + "- apply_patch: apply multi-file patches", + `- ${execToolName}: run shell commands (supports background via yieldMs/background)`, + `- ${processToolName}: manage background exec sessions`, + "- browser: control clawd's dedicated browser", + "- canvas: present/eval/snapshot the Canvas", + "- nodes: list/describe/notify/camera/screen on paired nodes", + "- cron: manage cron jobs and wake events (use for reminders; when scheduling a reminder, write the systemEvent text as something that will read like a reminder when it fires, and mention that it is a reminder depending on the time gap between setting and firing; include recent context in reminder text if appropriate)", + "- sessions_list: list sessions", + "- sessions_history: fetch session history", + "- sessions_send: send to another session", + ].join("\n"), "TOOLS.md does not control tool availability; it is user guidance for how to use external tools.", "If a task is more complex or takes longer, spawn a sub-agent. It will do the work for you and ping you when it's done. You can always check up on it.", "", @@ -375,11 +375,11 @@ export function buildAgentSystemPrompt(params: { hasGateway && !isMinimal ? "## Moltbot Self-Update" : "", hasGateway && !isMinimal ? [ - "Get Updates (self-update) is ONLY allowed when the user explicitly asks for it.", - "Do not run config.apply or update.run unless the user explicitly requests an update or config change; if it's not explicit, ask first.", - "Actions: config.get, config.schema, config.apply (validate + write full config, then restart), update.run (update deps or git, then restart).", - "After restart, Moltbot pings the last active session automatically.", - ].join("\n") + "Get Updates (self-update) is ONLY allowed when the user explicitly asks for it.", + "Do not run config.apply or update.run unless the user explicitly requests an update or config change; if it's not explicit, ask first.", + "Actions: config.get, config.schema, config.apply (validate + write full config, then restart), update.run (update deps or git, then restart).", + "After restart, Moltbot pings the last active session automatically.", + ].join("\n") : "", hasGateway && !isMinimal ? "" : "", "", @@ -401,55 +401,56 @@ export function buildAgentSystemPrompt(params: { "", ...(runtimeInfo?.os?.toLowerCase().includes("windows") ? [ - "## Windows Shell Guidance", - "You are running on Windows (PowerShell).", - "- Use PowerShell syntax (e.g. `$env:VAR` instead of `%VAR%` or `$VAR`).", - "- Do NOT use Unix commands like `grep`, `sed`, `awk`, `head`, `tail` in exec/shell (PowerShell) commands unless you are sure they are installed. Pi's built-in tools named `grep`, `find`, and `ls` are safe to use.", - "- Use `findstr` or `Select-String` instead of `grep`.", - "- Use `Get-ChildItem` (dir/ls) with `-Recurse` instead of `find`.", - "", - ] + "## Windows Shell Guidance", + "You are running on Windows (PowerShell).", + "- Use PowerShell syntax (e.g. `$env:VAR` instead of `%VAR%` or `$VAR`).", + "- Do NOT use Unix commands like `grep`, `sed`, `awk`, `head`, `tail` in exec/shell (PowerShell) commands unless you are sure they are installed. Pi's built-in tools named `grep`, `find`, and `ls` are safe to use.", + "- Use `findstr` or `Select-String` instead of `grep`.", + "- Use `Get-ChildItem` (dir/ls) with `-Recurse` instead of `find`.", + "", + ] : []), ...docsSection, params.sandboxInfo?.enabled ? "## Sandbox" : "", params.sandboxInfo?.enabled ? [ - "You are running in a sandboxed runtime (tools execute in Docker).", - "Some tools may be unavailable due to sandbox policy.", - "Sub-agents stay sandboxed (no elevated/host access). Need outside-sandbox read/write? Don't spawn; ask first.", - params.sandboxInfo.workspaceDir - ? `Sandbox workspace: ${params.sandboxInfo.workspaceDir}` - : "", - params.sandboxInfo.workspaceAccess - ? `Agent workspace access: ${params.sandboxInfo.workspaceAccess}${params.sandboxInfo.agentWorkspaceMount - ? ` (mounted at ${params.sandboxInfo.agentWorkspaceMount})` - : "" - }` - : "", - params.sandboxInfo.browserBridgeUrl ? "Sandbox browser: enabled." : "", - params.sandboxInfo.browserNoVncUrl - ? `Sandbox browser observer (noVNC): ${params.sandboxInfo.browserNoVncUrl}` - : "", - params.sandboxInfo.hostBrowserAllowed === true - ? "Host browser control: allowed." - : params.sandboxInfo.hostBrowserAllowed === false - ? "Host browser control: blocked." + "You are running in a sandboxed runtime (tools execute in Docker).", + "Some tools may be unavailable due to sandbox policy.", + "Sub-agents stay sandboxed (no elevated/host access). Need outside-sandbox read/write? Don't spawn; ask first.", + params.sandboxInfo.workspaceDir + ? `Sandbox workspace: ${params.sandboxInfo.workspaceDir}` : "", - params.sandboxInfo.elevated?.allowed - ? "Elevated exec is available for this session." - : "", - params.sandboxInfo.elevated?.allowed - ? "User can toggle with /elevated on|off|ask|full." - : "", - params.sandboxInfo.elevated?.allowed - ? "You may also send /elevated on|off|ask|full when needed." - : "", - params.sandboxInfo.elevated?.allowed - ? `Current elevated level: ${params.sandboxInfo.elevated.defaultLevel} (ask runs exec on host with approvals; full auto-approves).` - : "", - ] - .filter(Boolean) - .join("\n") + params.sandboxInfo.workspaceAccess + ? `Agent workspace access: ${params.sandboxInfo.workspaceAccess}${ + params.sandboxInfo.agentWorkspaceMount + ? ` (mounted at ${params.sandboxInfo.agentWorkspaceMount})` + : "" + }` + : "", + params.sandboxInfo.browserBridgeUrl ? "Sandbox browser: enabled." : "", + params.sandboxInfo.browserNoVncUrl + ? `Sandbox browser observer (noVNC): ${params.sandboxInfo.browserNoVncUrl}` + : "", + params.sandboxInfo.hostBrowserAllowed === true + ? "Host browser control: allowed." + : params.sandboxInfo.hostBrowserAllowed === false + ? "Host browser control: blocked." + : "", + params.sandboxInfo.elevated?.allowed + ? "Elevated exec is available for this session." + : "", + params.sandboxInfo.elevated?.allowed + ? "User can toggle with /elevated on|off|ask|full." + : "", + params.sandboxInfo.elevated?.allowed + ? "You may also send /elevated on|off|ask|full when needed." + : "", + params.sandboxInfo.elevated?.allowed + ? `Current elevated level: ${params.sandboxInfo.elevated.defaultLevel} (ask runs exec on host with approvals; full auto-approves).` + : "", + ] + .filter(Boolean) + .join("\n") : "", params.sandboxInfo?.enabled ? "" : "", ...buildUserIdentitySection(ownerLine, isMinimal), @@ -482,22 +483,22 @@ export function buildAgentSystemPrompt(params: { const guidanceText = level === "minimal" ? [ - `Reactions are enabled for ${channel} in MINIMAL mode.`, - "React ONLY when truly relevant:", - "- Acknowledge important user requests or confirmations", - "- Express genuine sentiment (humor, appreciation) sparingly", - "- Avoid reacting to routine messages or your own replies", - "Guideline: at most 1 reaction per 5-10 exchanges.", - ].join("\n") + `Reactions are enabled for ${channel} in MINIMAL mode.`, + "React ONLY when truly relevant:", + "- Acknowledge important user requests or confirmations", + "- Express genuine sentiment (humor, appreciation) sparingly", + "- Avoid reacting to routine messages or your own replies", + "Guideline: at most 1 reaction per 5-10 exchanges.", + ].join("\n") : [ - `Reactions are enabled for ${channel} in EXTENSIVE mode.`, - "Feel free to react liberally:", - "- Acknowledge messages with appropriate emojis", - "- Express sentiment and personality through reactions", - "- React to interesting content, humor, or notable events", - "- Use reactions to confirm understanding or agreement", - "Guideline: react whenever it feels natural.", - ].join("\n"); + `Reactions are enabled for ${channel} in EXTENSIVE mode.`, + "Feel free to react liberally:", + "- Acknowledge messages with appropriate emojis", + "- Express sentiment and personality through reactions", + "- React to interesting content, humor, or notable events", + "- Use reactions to confirm understanding or agreement", + "Guideline: react whenever it feels natural.", + ].join("\n"); lines.push("## Reactions", guidanceText, ""); } if (reasoningHint) { diff --git a/system-prompt.original.ts b/system-prompt.original.ts new file mode 100644 index 0000000000000000000000000000000000000000..0360ca3962a26c3cbb02b63fdfb5c9edfb588453 GIT binary patch literal 51122 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 literal 0 HcmV?d00001