fix(copilot): inject working directory into SDK prompt + workspace download links - #12215
Conversation
The tool supplement previously used a static `/tmp/copilot-<session>/` placeholder, so the agent had no idea what its real working directory was and wasted turns probing wrong paths before getting an error. Now the exact cwd is pre-computed and formatted into the prompt so the agent knows immediately where it can read and write.
- Wrap _make_sdk_cwd() in try/except so a ValueError yields a clean StreamError rather than propagating outside the stream error path - Reuse _precomputed_cwd inside the try block instead of recomputing, ensuring the system prompt and execution directory cannot drift - Reset frontend files (useCredits.ts, client.ts) to dev state — they were carried in from a master hotfix that is not yet in dev
makedirs can raise OSError which was previously outside the stream error-handling path. Move it into the early try/except alongside _make_sdk_cwd, widen the catch to (ValueError, OSError), and remove the now-redundant sdk_cwd = "" initialiser — sdk_cwd is assigned directly from _precomputed_cwd before the main try block.
_precomputed_cwd was a pointless intermediate. sdk_cwd is now set directly from _make_sdk_cwd() in the early try/except and used everywhere, eliminating the redundant variable.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughReplaces a static SDK tool supplement with Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant CopilotService
participant Filesystem
participant StreamHandler
Client->>CopilotService: start stream_chat_completion_sdk request
CopilotService->>Filesystem: ensure/create sdk_cwd
Filesystem-->>CopilotService: cwd path or error
alt cwd valid
CopilotService->>CopilotService: _build_sdk_tool_supplement(cwd)
CopilotService->>StreamHandler: assemble system prompt (with supplement) and start stream
StreamHandler-->>Client: stream events / transcripts
else cwd invalid
CopilotService-->>Client: emit StreamError and abort
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🔍 PR Overlap DetectionThis check compares your PR against all other open PRs targeting the same branch to detect potential merge conflicts early. 🔴 Merge Conflicts DetectedThe following PRs have been tested and will have merge conflicts if merged after this PR. Consider coordinating with the authors.
🟢 Low Risk — File Overlap OnlyThese PRs touch the same files but different sections (click to expand)
Summary: 1 conflict(s), 0 medium risk, 4 low risk (out of 5 PRs with file overlap) Auto-generated on push. Ignores: |
Add download_url + mime_type to WorkspaceWriteResponse so the agent always has a ready-to-paste workspace:// URL after saving a file. Add a "Sharing files with the user" section to the SDK tool supplement so the agent knows to embed workspace://id#mime_type as Markdown links ([file](url)) or inline images/video () in its replies.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@autogpt_platform/backend/backend/copilot/tools/workspace_files.py`:
- Around line 687-698: The download_url embeds rec.mime_type raw, which can
contain spaces/params that break URLs; URL-encode (or otherwise normalize)
rec.mime_type before inserting it into the fragment. Update the construction of
download_url used when building WorkspaceWriteResponse so it uses a
safely-encoded mime string (e.g., apply urllib.parse.quote or equivalent to
rec.mime_type.strip() and insert that encoded value), keep the fallback behavior
when rec.mime_type is falsy, and ensure the symbol names to edit are
download_url, rec.mime_type, and WorkspaceWriteResponse construction.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
autogpt_platform/backend/backend/copilot/sdk/service.pyautogpt_platform/backend/backend/copilot/tools/workspace_files.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Seer Code Review
- GitHub Check: types
- GitHub Check: test (3.12)
- GitHub Check: test (3.13)
- GitHub Check: test (3.11)
- GitHub Check: Check PR Status
🧰 Additional context used
📓 Path-based instructions (4)
autogpt_platform/backend/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/backend/**/*.py: Use Python 3.11 (required; managed by Poetry via pyproject.toml) for backend development
Always run 'poetry run format' (Black + isort) before linting in backend development
Always run 'poetry run lint' (ruff) after formatting in backend development
Files:
autogpt_platform/backend/backend/copilot/tools/workspace_files.pyautogpt_platform/backend/backend/copilot/sdk/service.py
autogpt_platform/backend/**/*.{py,txt}
📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)
Use
poetry runprefix for all Python commands, including testing, linting, formatting, and migrations
Files:
autogpt_platform/backend/backend/copilot/tools/workspace_files.pyautogpt_platform/backend/backend/copilot/sdk/service.py
autogpt_platform/backend/backend/**/*.py
📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)
Use Prisma ORM for database operations in PostgreSQL with pgvector for embeddings
Files:
autogpt_platform/backend/backend/copilot/tools/workspace_files.pyautogpt_platform/backend/backend/copilot/sdk/service.py
autogpt_platform/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
Format Python code with
poetry run format
Files:
autogpt_platform/backend/backend/copilot/tools/workspace_files.pyautogpt_platform/backend/backend/copilot/sdk/service.py
🧬 Code graph analysis (1)
autogpt_platform/backend/backend/copilot/sdk/service.py (2)
autogpt_platform/backend/backend/copilot/response_model.py (1)
StreamError(189-209)autogpt_platform/backend/backend/copilot/service.py (1)
_build_system_prompt(211-242)
🔇 Additional comments (3)
autogpt_platform/backend/backend/copilot/tools/workspace_files.py (1)
217-221: Nice addition to the write response contract.Adding
mime_typeanddownload_urltoWorkspaceWriteResponsecleanly supports the new sharing workflow.autogpt_platform/backend/backend/copilot/sdk/service.py (2)
90-158: Good improvement to inject the real session cwd into the SDK instructions.This removes placeholder drift and gives the agent precise path context for tool calls.
489-510: Good fail-fast handling around SDK cwd initialization.Catching cwd setup errors and returning a
StreamErrorat Line 501-Line 504 provides a cleaner user-visible failure path.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@autogpt_platform/backend/backend/copilot/sdk/service.py`:
- Around line 513-534: The cwd and prompt preflight (_make_sdk_cwd, os.makedirs,
_build_system_prompt, _build_sdk_tool_supplement) must be executed inside the
same protected try/finally that manages the session lock so any early
yield/return still triggers cleanup; move the sdk_cwd creation, os.makedirs, the
call to _build_system_prompt and the suffixing of _build_sdk_tool_supplement
into that try block (or restructure to avoid returning before the finally) so
that lock.release() in the finally always runs even if you yield StreamError or
_build_system_prompt raises.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
autogpt_platform/backend/backend/copilot/sdk/service.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: Seer Code Review
- GitHub Check: types
- GitHub Check: test (3.11)
- GitHub Check: test (3.12)
- GitHub Check: test (3.13)
- GitHub Check: Check PR Status
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (4)
autogpt_platform/backend/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/backend/**/*.py: Use Python 3.11 (required; managed by Poetry via pyproject.toml) for backend development
Always run 'poetry run format' (Black + isort) before linting in backend development
Always run 'poetry run lint' (ruff) after formatting in backend development
Files:
autogpt_platform/backend/backend/copilot/sdk/service.py
autogpt_platform/backend/**/*.{py,txt}
📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)
Use
poetry runprefix for all Python commands, including testing, linting, formatting, and migrations
Files:
autogpt_platform/backend/backend/copilot/sdk/service.py
autogpt_platform/backend/backend/**/*.py
📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)
Use Prisma ORM for database operations in PostgreSQL with pgvector for embeddings
Files:
autogpt_platform/backend/backend/copilot/sdk/service.py
autogpt_platform/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
Format Python code with
poetry run format
Files:
autogpt_platform/backend/backend/copilot/sdk/service.py
🧠 Learnings (1)
📚 Learning: 2026-02-26T17:02:22.448Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12211
File: .pre-commit-config.yaml:160-179
Timestamp: 2026-02-26T17:02:22.448Z
Learning: Keep the pre-commit hook pattern broad for autogpt_platform/backend to ensure OpenAPI schema changes are captured. Do not narrow to backend/api/ alone, since the generated schema depends on Pydantic models across multiple directories (backend/data/, backend/blocks/, backend/copilot/, backend/integrations/, backend/util/). Narrowing could miss schema changes and cause frontend type desynchronization.
Applied to files:
autogpt_platform/backend/backend/copilot/sdk/service.py
🧬 Code graph analysis (1)
autogpt_platform/backend/backend/copilot/sdk/service.py (2)
autogpt_platform/backend/backend/copilot/response_model.py (1)
StreamError(189-209)autogpt_platform/backend/backend/copilot/service.py (1)
_build_system_prompt(211-242)
🔇 Additional comments (1)
autogpt_platform/backend/backend/copilot/sdk/service.py (1)
90-149: Nice improvement: the SDK tool guidance is now session-accurate and actionable.Injecting the actual
cwdand documentingdownload_urlusage directly in the supplement should materially reduce wrong-path tool calls and improve file-sharing behavior in responses.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
autogpt_platform/backend/backend/copilot/tools/workspace_files.py (1)
687-701:⚠️ Potential issue | 🟠 MajorEncode the MIME fragment before embedding in
download_url.At Line 689, normalization helps, but direct interpolation can still break link parsing if
mime_typecontains unexpected fragment-breaking characters. Please URL-encode the fragment before composingworkspace://...#....🔧 Proposed fix
+from urllib.parse import quote @@ - normalized_mime = (rec.mime_type or "").split(";", 1)[0].strip().lower() + normalized_mime = (rec.mime_type or "").split(";", 1)[0].strip().lower() + mime_fragment = quote(normalized_mime, safe="/+.-") download_url = ( - f"workspace://{rec.id}#{normalized_mime}" + f"workspace://{rec.id}#{mime_fragment}" if normalized_mime else f"workspace://{rec.id}" )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@autogpt_platform/backend/backend/copilot/tools/workspace_files.py` around lines 687 - 701, The download_url currently embeds normalized_mime directly which can break the fragment; URL-encode the fragment before composing download_url so unsafe characters are percent-encoded (use a URL-encoding utility such as urllib.parse.quote on normalized_mime), keep the existing logic that omits the fragment when normalized_mime is empty, and ensure the WorkspaceWriteResponse fields (file_id/name/path/mime_type/size_bytes/download_url) still use the normalized_mime for mime_type while download_url uses the encoded fragment; update the code around normalized_mime and download_url to apply the encoding.
🧹 Nitpick comments (1)
autogpt_platform/frontend/src/app/globals.css (1)
184-187: Use a design token instead of hardcodedblack.At Line 186,
color: black;bypasses the design-token/Tailwind convention. Prefer a token-backed style like@apply text-foreground;(or equivalent token variable) for consistency.As per coding guidelines, "Use Tailwind CSS only for styling, use design tokens, and use Phosphor Icons only."♻️ Proposed fix
[data-streamdown="link-safety-modal"] button:last-of-type { - color: black; + `@apply` text-foreground; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@autogpt_platform/frontend/src/app/globals.css` around lines 184 - 187, The rule targeting [data-streamdown="link-safety-modal"] button:last-of-type uses a hardcoded color (color: black); replace that with the design-token/Tailwind-backed value instead (for example use `@apply` text-foreground or the corresponding CSS variable like var(--color-foreground)) so styling follows the token/Tailwind convention; update the selector [data-streamdown="link-safety-modal"] button:last-of-type to remove color: black and apply the token-based class/value.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@autogpt_platform/backend/backend/copilot/tools/workspace_files.py`:
- Around line 687-701: The download_url currently embeds normalized_mime
directly which can break the fragment; URL-encode the fragment before composing
download_url so unsafe characters are percent-encoded (use a URL-encoding
utility such as urllib.parse.quote on normalized_mime), keep the existing logic
that omits the fragment when normalized_mime is empty, and ensure the
WorkspaceWriteResponse fields
(file_id/name/path/mime_type/size_bytes/download_url) still use the
normalized_mime for mime_type while download_url uses the encoded fragment;
update the code around normalized_mime and download_url to apply the encoding.
---
Nitpick comments:
In `@autogpt_platform/frontend/src/app/globals.css`:
- Around line 184-187: The rule targeting [data-streamdown="link-safety-modal"]
button:last-of-type uses a hardcoded color (color: black); replace that with the
design-token/Tailwind-backed value instead (for example use `@apply`
text-foreground or the corresponding CSS variable like var(--color-foreground))
so styling follows the token/Tailwind convention; update the selector
[data-streamdown="link-safety-modal"] button:last-of-type to remove color: black
and apply the token-based class/value.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
autogpt_platform/backend/backend/copilot/tools/workspace_files.pyautogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/globals.css
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: types
- GitHub Check: end-to-end tests
- GitHub Check: test (3.13)
- GitHub Check: test (3.12)
- GitHub Check: test (3.11)
- GitHub Check: Check PR Status
🧰 Additional context used
📓 Path-based instructions (14)
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{ts,tsx,js,jsx}: Use Node.js 21+ with pnpm package manager for frontend development
Always run 'pnpm format' for formatting and linting code in frontend development
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/**/*.{tsx,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{tsx,ts}: Use function declarations for components and handlers (not arrow functions) in React components
Only use arrow functions for small inline lambdas (map, filter, etc.) in React components
Use PascalCase for component names and camelCase with 'use' prefix for hook names in React
Use Tailwind CSS utilities only for styling in frontend components
Use design system components from 'src/components/' (atoms, molecules, organisms) in frontend development
Never use 'src/components/legacy/' in frontend code
Only use Phosphor Icons (@phosphor-icons/react) for icons in frontend components
Use generated API hooks from '@/app/api/generated/endpoints/' instead of deprecated 'BackendAPI' or 'src/lib/autogpt-server-api/'
Use React Query for server state (via generated hooks) in frontend development
Default to client components ('use client') in Next.js; only use server components for SEO or extreme TTFB needs
Use '' component for rendering errors in frontend UI; use toast notifications for mutation errors; use 'Sentry.captureException()' for manual exceptions
Separate render logic from data/behavior in React components; keep comments minimal (code should be self-documenting)
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/frontend/**/*.{ts,tsx}: No barrel files or 'index.ts' re-exports in frontend code
Regenerate API hooks with 'pnpm generate:api' after backend OpenAPI spec changes in frontend development
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)
autogpt_platform/frontend/src/**/*.{ts,tsx}: Fully capitalize acronyms in symbols, e.g.graphID,useBackendAPI
Use function declarations (not arrow functions) for components and handlers
Separate render logic (.tsx) from business logic (use*.tshooks)
Use shadcn/ui (Radix UI primitives) with Tailwind CSS styling for UI components
Use Phosphor Icons only for icons
Use ErrorCard for render errors, toast for mutations, and Sentry for exceptions
Use design system components fromsrc/components/(atoms, molecules, organisms)
Never usesrc/components/__legacy__/*components
Use generated API hooks from@/app/api/__generated__/endpoints/with patternuse{Method}{Version}{OperationName}
Use Tailwind CSS only for styling, with design tokens
Do not useuseCallbackoruseMemounless asked to optimize a given function
Never type withanyunless a variable/attribute can ACTUALLY be of any type
autogpt_platform/frontend/src/**/*.{ts,tsx}: Structure components asComponentName/ComponentName.tsx+useComponentName.ts+helpers.tsand use design system components fromsrc/components/(atoms, molecules, organisms)
Use generated API hooks from@/app/api/__generated__/endpoints/with patternuse{Method}{Version}{OperationName}and regenerate withpnpm generate:api
Use function declarations (not arrow functions) for components and handlers
Separate render logic from business logic with component.tsx + useComponent.ts + helpers.ts structure
Colocate state when possible, avoid creating large components, use sub-components in local/componentsfolder
Avoid large hooks, abstract logic intohelpers.tsfiles when sensible
Use arrow functions only for callbacks, not for component declarations
Avoid comments at all times unless the code is very complex
Do not useuseCallbackoruseMemounless asked to optimize a given function
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/src/app/(platform)/**/components/**/*.{ts,tsx}
📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)
Put sub-components in local
components/folder within feature directories
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/src/**/*.tsx
📄 CodeRabbit inference engine (autogpt_platform/frontend/CLAUDE.md)
Component props should be
type Props = { ... }(not exported) unless it needs to be used outside the componentComponent props should be
interface Props { ... }(not exported) unless the interface needs to be used outside the component
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx}: Format frontend code usingpnpm format
Never use components fromsrc/components/__legacy__/*
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/**/*.{js,jsx,ts,tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
Use Tailwind CSS only for styling, use design tokens, and use Phosphor Icons only
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsxautogpt_platform/frontend/src/app/globals.css
autogpt_platform/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never type with
any, if no types available useunknown
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/frontend/src/app/(platform)/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
If adding protected frontend routes, update
frontend/lib/supabase/middleware.ts
Files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
autogpt_platform/backend/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/backend/**/*.py: Use Python 3.11 (required; managed by Poetry via pyproject.toml) for backend development
Always run 'poetry run format' (Black + isort) before linting in backend development
Always run 'poetry run lint' (ruff) after formatting in backend development
Files:
autogpt_platform/backend/backend/copilot/tools/workspace_files.py
autogpt_platform/backend/**/*.{py,txt}
📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)
Use
poetry runprefix for all Python commands, including testing, linting, formatting, and migrations
Files:
autogpt_platform/backend/backend/copilot/tools/workspace_files.py
autogpt_platform/backend/backend/**/*.py
📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)
Use Prisma ORM for database operations in PostgreSQL with pgvector for embeddings
Files:
autogpt_platform/backend/backend/copilot/tools/workspace_files.py
autogpt_platform/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
Format Python code with
poetry run format
Files:
autogpt_platform/backend/backend/copilot/tools/workspace_files.py
🧠 Learnings (5)
📚 Learning: 2026-02-26T10:12:58.845Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12207
File: autogpt_platform/frontend/src/components/ai-elements/conversation.tsx:0-0
Timestamp: 2026-02-26T10:12:58.845Z
Learning: Guideline: Do not apply dark mode CSS classes (e.g., dark:text-*) to copilot UI components until dark mode support is implemented. Applies to all copilot-related components (paths containing /copilot/). When reviewing, search for dark:* class names within copilot components and refactor to use conditional class sets or feature-flag gates, ensuring no dark-mode styles are present in the code paths that render copilot UI unless dark mode support is officially enabled.
Applied to files:
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
📚 Learning: 2026-02-04T16:50:51.495Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T16:50:51.495Z
Learning: Applies to autogpt_platform/frontend/**/*.{js,jsx,ts,tsx,css} : Use Tailwind CSS only for styling, use design tokens, and use Phosphor Icons only
Applied to files:
autogpt_platform/frontend/src/app/globals.css
📚 Learning: 2026-02-04T16:50:33.615Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/frontend/CLAUDE.md:0-0
Timestamp: 2026-02-04T16:50:33.615Z
Learning: Applies to autogpt_platform/frontend/src/**/*.{ts,tsx} : Use Tailwind CSS only for styling, with design tokens
Applied to files:
autogpt_platform/frontend/src/app/globals.css
📚 Learning: 2026-02-26T10:12:58.845Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12207
File: autogpt_platform/frontend/src/components/ai-elements/conversation.tsx:0-0
Timestamp: 2026-02-26T10:12:58.845Z
Learning: The copilot feature in autogpt_platform/frontend/src/app/(platform)/copilot does not currently support dark mode, so dark mode CSS classes (like dark:text-neutral-400) should not be added to copilot components until dark mode support is implemented.
Applied to files:
autogpt_platform/frontend/src/app/globals.css
📚 Learning: 2026-02-26T17:02:22.448Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12211
File: .pre-commit-config.yaml:160-179
Timestamp: 2026-02-26T17:02:22.448Z
Learning: Keep the pre-commit hook pattern broad for autogpt_platform/backend to ensure OpenAPI schema changes are captured. Do not narrow to backend/api/ alone, since the generated schema depends on Pydantic models across multiple directories (backend/data/, backend/blocks/, backend/copilot/, backend/integrations/, backend/util/). Narrowing could miss schema changes and cause frontend type desynchronization.
Applied to files:
autogpt_platform/backend/backend/copilot/tools/workspace_files.py
🔇 Additional comments (2)
autogpt_platform/backend/backend/copilot/tools/workspace_files.py (1)
217-221: Response contract extension is consistent.Adding
mime_typeanddownload_urltoWorkspaceWriteResponsealigns cleanly with the write flow and improves downstream rendering/linking clarity.autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx (1)
107-116: Absolute URL handling is a solid improvement.The
windowguard at Line 114 is safe, and the absolute URL path improves Streamdown “Copy link” behavior without breaking non-browser fallback.
autogpt-reviewer
left a comment
There was a problem hiding this comment.
PR #12215 — fix(copilot): inject actual working directory into SDK system prompt
Author: @majdyz | Reviewer: @ntindle | Files: service.py (+45/-12), workspace_files.py (+11/-0)
🎯 Verdict: APPROVE_WITH_CONDITIONS
What This PR Does
The SDK copilot agent was seeing a hardcoded placeholder path (/tmp/copilot-<session>/) in its system prompt instead of its real working directory. This caused the agent to reference wrong paths in tool calls. This PR replaces the static _SDK_TOOL_SUPPLEMENT constant with a _build_sdk_tool_supplement(cwd) function that injects the session-specific working directory, moves os.makedirs earlier for fail-fast error handling via StreamError, and adds mime_type/download_url fields to WorkspaceWriteResponse to support file sharing.
Specialist Findings
🛡️ Security ✅ — Path traversal thoroughly defended: double sanitization chain (make_session_path regex strip → normpath → prefix check, then _make_sdk_cwd repeats normpath + startswith). No injection risk in the f-string prompt since cwd can only contain /tmp/copilot- + [A-Za-z0-9-]. No secrets exposure. Two informational items: os.makedirs could use explicit mode=0o700 (defense-in-depth), and mime_type in download_url fragment could benefit from a whitelist — neither blocking.
🏗️ Architecture ✅ — Clean refactor following existing _build_* naming convention. CWD hoisting achieves proper fail-fast semantics. sdk_cwd computed once and reused everywhere — no drift. WorkspaceWriteResponse expansion mirrors existing read-path patterns.
download_url format inconsistency: read tool produces workspace://{id} while write tool produces workspace://{id}#{mime_type} — should extract shared _workspace_url() helper. (Cross-confirmed by Quality specialist)
⚡ Performance ✅ — No regression. Same O(1) path construction and mkdir, now built dynamically instead of static (~µs of string formatting). download_url is a tiny string concat using data already in memory. The early-exit error handling is marginally better for resource usage on failure paths.
🧪 Testing
_build_sdk_tool_supplement()is a pure function — trivial to unit test, not testedStreamErrorearly-return on cwd failure is a new abort path for the entire SDK stream — untestedWorkspaceWriteResponse.mime_typeand.download_url— existing e2e tests never assert on themdownload_urlbranching (with vs without mime_type) — untested- Most concerning:
StreamErrorfires beforeStreamStartis yielded — new failure mode that needs frontend validation
📖 Quality ✅ — Readability score A. Clean f-string prompt, consistent style. CodeRabbit's 66.67% docstring coverage flag is because new Pydantic fields lack Field(description=...) annotations. Minor: mime_type: str with empty-string sentinel should be str | None = None for Pythonic "unknown" handling.
📦 Product ✅ — Core UX problem cleanly resolved. File-sharing prompt additions (inline images, video player, download links) are well-structured. Error handling is graceful with clean StreamError. One nice-to-have: error message "Unable to initialize working directory" could suggest retry/new session.
📬 Discussion 12f5317). One unresolved dispute: CodeRabbit flagged that _build_system_prompt() runs after lock acquisition but before the outer try/finally — if it raises, lock.release() in finally is skipped and the lock leaks until TTL. Author dismissed; CodeRabbit disagreed with code verification. The sdk_cwd_error return path is safe (runs before lock), but _build_system_prompt raising after lock acquisition is a real concern. Also: MIME normalization was added but urllib.parse.quote() encoding was not. PR #12212 (same author) has 2 conflicts in service.py.
🔎 QA ✅ — Core fix verified end-to-end. Asked copilot "What is your current working directory?" → responded with /tmp/copilot-e5f7ea51-bff1-44f8-bc72-e01e429ec153 (real UUID path, NOT placeholder). Frontend loads cleanly: landing, login, signup, copilot, library, build pages all render. Workspace write fallback behavior correct (GCP storage unavailable in local env — expected). No regressions observed.
Blockers
None — ntindle has already approved on HEAD. The conditions below are strong recommendations, not merge-blockers.
Should Fix (Follow-up OK)
service.py:507-510— Lock safety: Move_build_system_prompt()+_build_sdk_tool_supplement()calls inside the outertryblock solock.release()infinallyis guaranteed. Currently, an exception in prompt building after lock acquisition leaks the lock until TTL. (Flagged by CodeRabbit, Discussion analyst confirmed)workspace_files.py:512 vs :687—download_urlformat inconsistency: Read tool producesworkspace://{id}, write tool producesworkspace://{id}#{mime_type}. Extract a shared_workspace_url(file_id, mime_type=None)helper. (Cross-confirmed by Architect + Quality)service.py+workspace_files.py— Add basic tests: At minimum, unit test_build_sdk_tool_supplement()(pure function) and theStreamErrorearly-return path. (Flagged by Testing)workspace_files.py:224—mime_typetype: Usestr | None = Noneinstead ofstrwith empty-string sentinel.workspace_files.py:690— URL-encodemime_type: Applyurllib.parse.quote()torec.mime_typebefore embedding in URL fragment for robustness with exotic MIME types.
Risk Assessment
Merge risk: LOW | Rollback: EASY
The change is small, well-scoped, and confined to SDK copilot prompt construction + a response model extension. The core fix (cwd injection) is verified working. The lock safety issue is the only real concern, but it's a narrow race in prompt building and the lock has a TTL — low blast radius.
@ntindle Clean fix, QA-verified working. The lock safety item (#1 above) is worth a follow-up since CodeRabbit and our Discussion analyst both independently flagged it. The rest are nice-to-haves. Safe to merge with a note to address the lock safety in a follow-up.
There was a problem hiding this comment.
Already fixed — sdk_cwd creation is now inside the outer try: block (line 518), with _cleanup_sdk_tool_results(sdk_cwd) and lock.release() both in the corresponding finally: block (lines 1116–1120). The stale diff showed it outside the try block, but the current code has it properly scoped.


Summary
_SDK_TOOL_SUPPLEMENTplaceholder path with_build_sdk_tool_supplement(cwd: str)that injects the session-specific working directorysdk_cwdis computed once via_make_sdk_cwd(session_id),os.makedirsis called after lock acquisition (inside the protectedtry/finally), and the same variable is used everywhere — no drift between prompt and execution directoryValueError/OSErrorerror handling for cwd preparation with properStreamErroremissionworkspace://Markdown links (images render inline, videos render with player controls, other files as download links)WorkspaceWriteResponsenow includesdownload_url(pre-formattedworkspace://file_id#mimestring) and a normalisedmime_typefield (MIME parameters stripped, lowercased)workspace://regular links now resolve to absolute URLs so Streamdown's "Copy link" copies the full URL--primaryresolving to near-whiteMotivation
The SDK agent was seeing a hardcoded placeholder path in the system prompt instead of the real working directory, causing it to reference wrong paths in tool calls. Additionally, there was no guidance for the agent on how to share files it writes to the workspace with the user in chat.
Test plan
CHAT_USE_CLAUDE_AGENT_SDK=trueand verify the agent references the correctsdk_cwdpath in its tool callsworkspace://syntax