fix: delegate CompositeBackend.id to default sandbox backend (#286)

* fix: delegate CompositeBackend.id to default sandbox backend

CompositeBackend failed isSandboxBackend check because it lacked the
required id property from SandboxBackendProtocol. Added a get id()
getter that delegates to the default backend's id when it is a sandbox,
or returns an empty string otherwise. This preserves the real sandbox
ID (e.g. from Daytona/Deno/Modal) for external lifecycle operations
like provider.delete({ sandboxId: sandbox.id }).

Fixes #275

* Fix delegation of CompositeBackend.id to sandbox backend
This commit is contained in:
Youngho Kim
2026-03-10 01:23:54 +09:00
committed by GitHub
parent 1b8bde902f
commit 5f499ed5af
3 changed files with 43 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"deepagents": patch
---
fix: delegate CompositeBackend.id to default sandbox backend
@@ -18,6 +18,7 @@ import type {
SandboxBackendProtocol,
GrepMatch,
} from "./protocol.js";
import { isSandboxBackend } from "./protocol.js";
/**
* Mock sandbox backend for testing execute delegation
@@ -608,6 +609,38 @@ describe("CompositeBackend", () => {
"doesn't support command execution",
);
});
it("should pass isSandboxBackend check when default backend supports execution", () => {
const mockSandbox = new MockSandboxBackend();
const { stateAndStore } = makeConfig();
const composite = new CompositeBackend(mockSandbox, {
"/store/": new StoreBackend(stateAndStore),
});
expect(isSandboxBackend(composite)).toBe(true);
});
it("should delegate id to default sandbox backend", () => {
const mockSandbox = new MockSandboxBackend();
const { stateAndStore } = makeConfig();
const composite = new CompositeBackend(mockSandbox, {
"/store/": new StoreBackend(stateAndStore),
});
expect(composite.id).toBe("mock-sandbox");
});
it("should return empty string id when default backend is not sandbox", () => {
const { stateAndStore } = makeConfig();
const composite = new CompositeBackend(new StateBackend(stateAndStore), {
"/store/": new StoreBackend(stateAndStore),
});
expect(composite.id).toBe("");
});
});
describe("uploadFiles", () => {
@@ -42,6 +42,11 @@ export class CompositeBackend implements BackendProtocol {
);
}
/** Delegates to default backend's id if it is a sandbox, otherwise empty string. */
get id(): string {
return isSandboxBackend(this.default) ? this.default.id : "";
}
/**
* Determine which backend handles this key and strip prefix.
*