Skip to content

fix(copilot): inject working directory into SDK prompt + workspace download links - #12215

Merged
majdyz merged 9 commits into
devfrom
fix/copilot-sdk-cwd
Feb 26, 2026
Merged

fix(copilot): inject working directory into SDK prompt + workspace download links#12215
majdyz merged 9 commits into
devfrom
fix/copilot-sdk-cwd

Conversation

@majdyz

@majdyz majdyz commented Feb 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replaces the static _SDK_TOOL_SUPPLEMENT placeholder path with _build_sdk_tool_supplement(cwd: str) that injects the session-specific working directory
  • sdk_cwd is computed once via _make_sdk_cwd(session_id), os.makedirs is called after lock acquisition (inside the protected try/finally), and the same variable is used everywhere — no drift between prompt and execution directory
  • Added ValueError/OSError error handling for cwd preparation with proper StreamError emission
  • Teaches the SDK agent how to share workspace files with the user via workspace:// Markdown links (images render inline, videos render with player controls, other files as download links)
  • WorkspaceWriteResponse now includes download_url (pre-formatted workspace://file_id#mime string) and a normalised mime_type field (MIME parameters stripped, lowercased)
  • Frontend: workspace workspace:// regular links now resolve to absolute URLs so Streamdown's "Copy link" copies the full URL
  • Frontend: Streamdown's "Open link" button colour overridden to match the design system (violet accent) — previously near-invisible in dark mode due to --primary resolving to near-white

Motivation

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

  • CI green (test 3.11 / 3.12 / 3.13)
  • Start a copilot session with CHAT_USE_CLAUDE_AGENT_SDK=true and verify the agent references the correct sdk_cwd path in its tool calls
  • Ask the agent to write a file and confirm it responds with a clickable download link / inline image using the workspace:// syntax
  • Verify the "Open link" button in the Streamdown external-link dialog is visible in both light and dark mode
  • Click "Copy link" on a workspace file link and confirm it copies the full URL (including host)

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.
@majdyz
majdyz requested a review from a team as a code owner February 26, 2026 16:32
@majdyz
majdyz requested review from Bentlybro and kcze and removed request for a team February 26, 2026 16:32
@github-project-automation github-project-automation Bot moved this to 🆕 Needs initial review in AutoGPT development kanban Feb 26, 2026
@github-actions github-actions Bot added platform/backend AutoGPT Platform - Back end size/m labels Feb 26, 2026
@coderabbitai

coderabbitai Bot commented Feb 26, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Replaces a static SDK tool supplement with _build_sdk_tool_supplement(cwd: str), precomputes/validates and creates an SDK working directory (aborting with StreamError on failure), injects the built supplement into system prompts, adds mime_type and download_url to workspace write responses, and makes small frontend URL and CSS adjustments.

Changes

Cohort / File(s) Summary
SDK service & prompt construction
autogpt_platform/backend/backend/copilot/sdk/service.py
Adds _build_sdk_tool_supplement(cwd: str). Precomputes/validates sdk_cwd (creates directory), moves workflow init earlier, injects supplement into system prompt for normal and streaming paths, yields StreamError on invalid cwd, and updates in-file docs/comments.
Workspace files response shape
autogpt_platform/backend/backend/copilot/tools/workspace_files.py
Extends WorkspaceWriteResponse with mime_type and download_url. Normalizes MIME types and constructs workspace://<id>#<normalized_mime> download URLs when applicable; populates these fields after writes.
Frontend URL handling & styles
autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx, autogpt_platform/frontend/src/app/globals.css
Resolve non-image workspace URLs as absolute proxy URLs using window.origin when available (fallback preserved); adds Streamdown link-safety modal button style and removes table side borders for Streamdown tables.

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • ntindle
  • Bentlybro
  • kcze

Poem

🐰
I dug a cwd beneath the code,
Sewed prompts with paths along the road,
If folders fail — I thump and stop,
Else streams and links go hop-hop-hop,
A tiny carrot-built upload.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: replacing a static placeholder path with actual working directory injection in the SDK system prompt.
Description check ✅ Passed The description is directly related to the changeset, clearly explaining the motivation, implementation approach, and test plan for the SDK working directory injection fix.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/copilot-sdk-cwd

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Feb 26, 2026

Copy link
Copy Markdown
Contributor

🔍 PR Overlap Detection

This check compares your PR against all other open PRs targeting the same branch to detect potential merge conflicts early.

🔴 Merge Conflicts Detected

The following PRs have been tested and will have merge conflicts if merged after this PR. Consider coordinating with the authors.

🟢 Low Risk — File Overlap Only

These 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: openapi.json, lock files.

@majdyz
majdyz requested a review from ntindle February 26, 2026 16:34
@majdyz
majdyz enabled auto-merge February 26, 2026 16:34
Comment thread autogpt_platform/backend/backend/copilot/sdk/service.py Outdated
ntindle
ntindle previously approved these changes Feb 26, 2026
@github-project-automation github-project-automation Bot moved this from 🆕 Needs initial review to 👍🏼 Mergeable in AutoGPT development kanban Feb 26, 2026
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 (![alt](url)) in its replies.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

📥 Commits

Reviewing files that changed from the base of the PR and between 6dca806 and 0288964.

📒 Files selected for processing (2)
  • autogpt_platform/backend/backend/copilot/sdk/service.py
  • autogpt_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.py
  • autogpt_platform/backend/backend/copilot/sdk/service.py
autogpt_platform/backend/**/*.{py,txt}

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

Use poetry run prefix for all Python commands, including testing, linting, formatting, and migrations

Files:

  • autogpt_platform/backend/backend/copilot/tools/workspace_files.py
  • 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/tools/workspace_files.py
  • 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/tools/workspace_files.py
  • 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 (3)
autogpt_platform/backend/backend/copilot/tools/workspace_files.py (1)

217-221: Nice addition to the write response contract.

Adding mime_type and download_url to WorkspaceWriteResponse cleanly 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 StreamError at Line 501-Line 504 provides a cleaner user-visible failure path.

Comment thread autogpt_platform/backend/backend/copilot/tools/workspace_files.py
ntindle
ntindle previously approved these changes Feb 26, 2026
@github-actions github-actions Bot added the platform/frontend AutoGPT Platform - Front end label Feb 26, 2026
@majdyz
majdyz requested a review from ntindle February 26, 2026 17:06

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

📥 Commits

Reviewing files that changed from the base of the PR and between 0288964 and c55cb36.

📒 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 run prefix 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 cwd and documenting download_url usage directly in the supplement should materially reduce wrong-path tool calls and improve file-sharing behavior in responses.

Comment thread autogpt_platform/backend/backend/copilot/sdk/service.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
autogpt_platform/backend/backend/copilot/tools/workspace_files.py (1)

687-701: ⚠️ Potential issue | 🟠 Major

Encode the MIME fragment before embedding in download_url.

At Line 689, normalization helps, but direct interpolation can still break link parsing if mime_type contains unexpected fragment-breaking characters. Please URL-encode the fragment before composing workspace://...#....

🔧 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 hardcoded black.

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.

♻️ Proposed fix
 [data-streamdown="link-safety-modal"] button:last-of-type {
-  color: black;
+  `@apply` text-foreground;
 }
As per coding guidelines, "Use Tailwind CSS only for styling, use design tokens, and use Phosphor Icons only."
🤖 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.

📥 Commits

Reviewing files that changed from the base of the PR and between c55cb36 and b6d63a0.

📒 Files selected for processing (3)
  • autogpt_platform/backend/backend/copilot/tools/workspace_files.py
  • autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx
  • autogpt_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*.ts hooks)
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 from src/components/ (atoms, molecules, organisms)
Never use src/components/__legacy__/* components
Use generated API hooks from @/app/api/__generated__/endpoints/ with pattern use{Method}{Version}{OperationName}
Use Tailwind CSS only for styling, with design tokens
Do not use useCallback or useMemo unless asked to optimize a given function
Never type with any unless a variable/attribute can ACTUALLY be of any type

autogpt_platform/frontend/src/**/*.{ts,tsx}: Structure components as ComponentName/ComponentName.tsx + useComponentName.ts + helpers.ts and use design system components from src/components/ (atoms, molecules, organisms)
Use generated API hooks from @/app/api/__generated__/endpoints/ with pattern use{Method}{Version}{OperationName} and regenerate with pnpm 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 /components folder
Avoid large hooks, abstract logic into helpers.ts files 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 use useCallback or useMemo unless 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 component

Component 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 using pnpm format
Never use components from src/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.tsx
  • autogpt_platform/frontend/src/app/globals.css
autogpt_platform/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never type with any, if no types available use unknown

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 run prefix 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_type and download_url to WorkspaceWriteResponse aligns 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 window guard at Line 114 is safe, and the absolute URL path improves Streamdown “Copy link” behavior without breaking non-browser fallback.

@majdyz majdyz changed the title fix(copilot): inject actual working directory into SDK system prompt fix(copilot): inject working directory into SDK prompt + workspace download links Feb 26, 2026
@majdyz
majdyz added this pull request to the merge queue Feb 26, 2026

@autogpt-reviewer autogpt-reviewer left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ⚠️Zero test coverage added for any new code paths:

  • _build_sdk_tool_supplement() is a pure function — trivial to unit test, not tested
  • StreamError early-return on cwd failure is a new abort path for the entire SDK stream — untested
  • WorkspaceWriteResponse.mime_type and .download_url — existing e2e tests never assert on them
  • download_url branching (with vs without mime_type) — untested
  • Most concerning: StreamError fires before StreamStart is 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 ⚠️ntindle approved on HEAD (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.
copilot-cwd-response
copilot-workspace-write

Blockers

None — ntindle has already approved on HEAD. The conditions below are strong recommendations, not merge-blockers.

Should Fix (Follow-up OK)

  1. service.py:507-510 — Lock safety: Move _build_system_prompt() + _build_sdk_tool_supplement() calls inside the outer try block so lock.release() in finally is guaranteed. Currently, an exception in prompt building after lock acquisition leaks the lock until TTL. (Flagged by CodeRabbit, Discussion analyst confirmed)
  2. workspace_files.py:512 vs :687download_url format inconsistency: Read tool produces workspace://{id}, write tool produces workspace://{id}#{mime_type}. Extract a shared _workspace_url(file_id, mime_type=None) helper. (Cross-confirmed by Architect + Quality)
  3. service.py + workspace_files.py — Add basic tests: At minimum, unit test _build_sdk_tool_supplement() (pure function) and the StreamError early-return path. (Flagged by Testing)
  4. workspace_files.py:224mime_type type: Use str | None = None instead of str with empty-string sentinel.
  5. workspace_files.py:690 — URL-encode mime_type: Apply urllib.parse.quote() to rec.mime_type before 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.

Merged via the queue into dev with commit b30418d Feb 26, 2026
29 checks passed
@majdyz
majdyz deleted the fix/copilot-sdk-cwd branch February 26, 2026 17:44
@github-project-automation github-project-automation Bot moved this to Done in Frontend Feb 26, 2026
@github-project-automation github-project-automation Bot moved this from 👍🏼 Mergeable to ✅ Done in AutoGPT development kanban Feb 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform/backend AutoGPT Platform - Back end platform/frontend AutoGPT Platform - Front end size/l size/m

Projects

Status: ✅ Done
Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants