mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-17 08:01:03 +00:00
chore: recover hamburg workspace state
This commit is contained in:
parent
5d65013aa5
commit
196541394b
15 changed files with 1082 additions and 60 deletions
|
|
@ -378,31 +378,39 @@ class StreamableHttpAcpTransport {
|
|||
});
|
||||
|
||||
const url = this.buildUrl(this.bootstrapQueryIfNeeded());
|
||||
const response = await this.fetcher(url, {
|
||||
method: "POST",
|
||||
headers,
|
||||
body: JSON.stringify(message),
|
||||
});
|
||||
|
||||
this.postedOnce = true;
|
||||
|
||||
if (!response.ok) {
|
||||
throw new AcpHttpError(response.status, await readProblem(response), response);
|
||||
}
|
||||
|
||||
this.ensureSseLoop();
|
||||
void this.postMessage(url, headers, message);
|
||||
}
|
||||
|
||||
if (response.status === 200) {
|
||||
const text = await response.text();
|
||||
if (text.trim()) {
|
||||
const envelope = JSON.parse(text) as AnyMessage;
|
||||
this.pushInbound(envelope);
|
||||
private async postMessage(url: string, headers: Headers, message: AnyMessage): Promise<void> {
|
||||
try {
|
||||
const response = await this.fetcher(url, {
|
||||
method: "POST",
|
||||
headers,
|
||||
body: JSON.stringify(message),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new AcpHttpError(response.status, await readProblem(response), response);
|
||||
}
|
||||
} else {
|
||||
|
||||
if (response.status === 200) {
|
||||
const text = await response.text();
|
||||
if (text.trim()) {
|
||||
const envelope = JSON.parse(text) as AnyMessage;
|
||||
this.pushInbound(envelope);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Drain response body so the underlying connection is released back to
|
||||
// the pool. Without this, Node.js undici keeps the socket occupied and
|
||||
// the pool. Without this, Node.js undici keeps the socket occupied and
|
||||
// may stall subsequent requests to the same origin.
|
||||
await response.text().catch(() => {});
|
||||
} catch (error) {
|
||||
console.error("ACP write error:", error);
|
||||
this.failReadable(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,4 +140,54 @@ describe("AcpHttpClient integration", () => {
|
|||
|
||||
await client.disconnect();
|
||||
});
|
||||
|
||||
it("answers session/request_permission while session/prompt is still in flight", async () => {
|
||||
const permissionRequests: Array<{ sessionId: string; title?: string | null }> = [];
|
||||
const serverId = `acp-http-client-permissions-${Date.now().toString(36)}`;
|
||||
|
||||
const client = new AcpHttpClient({
|
||||
baseUrl,
|
||||
token,
|
||||
transport: {
|
||||
path: `/v1/acp/${encodeURIComponent(serverId)}`,
|
||||
bootstrapQuery: { agent: "mock" },
|
||||
},
|
||||
client: {
|
||||
requestPermission: async (request) => {
|
||||
permissionRequests.push({
|
||||
sessionId: request.sessionId,
|
||||
title: request.toolCall.title,
|
||||
});
|
||||
return {
|
||||
outcome: {
|
||||
outcome: "selected",
|
||||
optionId: "reject-once",
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await client.initialize();
|
||||
|
||||
const session = await client.newSession({
|
||||
cwd: process.cwd(),
|
||||
mcpServers: [],
|
||||
});
|
||||
|
||||
const prompt = await client.prompt({
|
||||
sessionId: session.sessionId,
|
||||
prompt: [{ type: "text", text: "please trigger permission" }],
|
||||
});
|
||||
|
||||
expect(prompt.stopReason).toBe("end_turn");
|
||||
expect(permissionRequests).toEqual([
|
||||
{
|
||||
sessionId: session.sessionId,
|
||||
title: "Write mock.txt",
|
||||
},
|
||||
]);
|
||||
|
||||
await client.disconnect();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue