Skip to content

fix(workplaces): delegate file I/O on LocalWorkplaceBackend#36

Open
DeryFerd wants to merge 1 commit into
anvie:mainfrom
DeryFerd:fix/workplace-local-backend-file-delegation
Open

fix(workplaces): delegate file I/O on LocalWorkplaceBackend#36
DeryFerd wants to merge 1 commit into
anvie:mainfrom
DeryFerd:fix/workplace-local-backend-file-delegation

Conversation

@DeryFerd
Copy link
Copy Markdown
Contributor

Background

#34 reports that any bash or runpy call from an agent bound to a local workplace dies immediately with:

TypeError: Can't instantiate abstract class LocalWorkplaceBackend
without an implementation for abstract methods
'file_exists', 'file_stat', 'make_dirs', 'read_file', 'write_file'

File tools (read_file, write_file, etc.) can still work because they often go through other backends. Shell and Python execution go through WorkplaceManagerLocalWorkplaceBackend, so the failure is total for those tools.

The class in backend/workplaces/backends/local_workplace.py has looked the same since v0.2.6. What changed is that ExecutionBackend in backend/tools/lib/exec_backend.py now declares five file I/O methods as @abstractmethod so tools like write_file and patch target the same environment as bash/runpy (Docker, SSH, workplace, etc.). LocalWorkplaceBackend never caught up, so Python refuses to construct it.

What this change does

Add five one-line delegators on LocalWorkplaceBackend, each forwarding to _get_inner():

  • file_exists
  • file_stat
  • read_file
  • write_file (including create_dirs)
  • make_dirs

_get_inner() already returns either LocalBackend or DockerBackend (sandbox path). Both inner classes implement the full interface, so there is no new logic, only wiring.

No change to workplace config, session routing, or sandbox defaults.

Files touched

File Change
backend/workplaces/backends/local_workplace.py Implement the five abstract methods
unit_tests/test_local_workplace_backend.py New tests

Tests

unit_tests/test_local_workplace_backend.py:

  • Instantiates LocalWorkplaceBackend and checks it is a concrete ExecutionBackend (would have failed before on 3.12+ abstract base enforcement).
  • Mocks the inner backend and asserts each file method calls through with the expected arguments.

How a reviewer can sanity-check

  1. Create a local workplace pointing at any directory.
  2. Attach an agent with bash and/or runpy.
  3. Run something trivial (pwd, print(1)).

Before: TypeError on first tool call. After: command runs in the workplace workspace.

I did not run a full fresh install in this PR; validation is unit tests plus the code path review above. Happy to run a manual pass if you want that noted in the PR thread.

Risk / compatibility

Low. The methods are pure delegation; behavior matches whatever LocalBackend or DockerBackend already does for non-workplace sessions.

Sandbox workplaces (sandbox_enabled=True) lazy-init DockerBackend on first use; file calls after that follow the same inner instance as run_bash.

Closes #34.

Delegate abstract file methods to the inner backend so bash and runpy work in local workplaces.

Fixes anvie#34

Co-authored-by: Cursor <cursoragent@cursor.com>
jankric pushed a commit to jankric/evonic that referenced this pull request May 16, 2026
jeffrysurya pushed a commit to jeffrysurya/evonic that referenced this pull request May 20, 2026
…ge, enhanced backend logging, visual distinction in Chat UI

backend/agent_runtime/concurrency.py:
  - Added capacity_details property to ConcurrencyGate ({active, max})
  - Added get_agent_capacity_details() to ConcurrencyManager

backend/agent_runtime/runtime.py:
  - Replaced vague busy-ack message with explicit concurrency limit info
    (e.g. 'Agent is at maximum concurrent capacity (2/1 slots in use)...')
  - Added concurrency_limited: True metadata alongside busy_ack: True
  - Enhanced logger output with [CONCURRENCY_LIMITED] tag, agent name,
    active/max slot counts, timestamp
  - Emitted concurrency_limited event (instead of generic turn_complete)
    with concurrency_active/concurrency_max fields

templates/agent_detail.html:
  - renderEntries now detects busy_ack/concurrency_limited on 'final'
    entries and renders them as system notifications ([SYSTEM/Concurrency])
    with distinct orange warning styling instead of regular assistant bubbles
  - pollForResponse now does the same for the SSE fallback path
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LocalWorkplaceBackend crashes on every bash/runpy call - v0.3.19

1 participant