@posthog/agent 2.3.125 → 2.3.131
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.js +4 -6
- package/dist/agent.js.map +1 -1
- package/dist/posthog-api.js +1 -1
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.d.ts +1 -0
- package/dist/server/agent-server.js +18 -14
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +18 -14
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +1 -1
- package/src/adapters/claude/permissions/permission-handlers.ts +7 -5
- package/src/server/agent-server.ts +15 -8
- package/src/server/question-relay.test.ts +65 -0
package/package.json
CHANGED
|
@@ -388,12 +388,14 @@ async function handleDefaultPermissionFlow(
|
|
|
388
388
|
updatedInput: toolInput as Record<string, unknown>,
|
|
389
389
|
};
|
|
390
390
|
} else {
|
|
391
|
-
const
|
|
391
|
+
const feedback = (
|
|
392
|
+
response._meta?.customInput as string | undefined
|
|
393
|
+
)?.trim();
|
|
394
|
+
const message = feedback
|
|
395
|
+
? `User refused permission to run tool with feedback: ${feedback}`
|
|
396
|
+
: "User refused permission to run tool";
|
|
392
397
|
await emitToolDenial(context, message);
|
|
393
|
-
return {
|
|
394
|
-
behavior: "deny",
|
|
395
|
-
message,
|
|
396
|
-
};
|
|
398
|
+
return { behavior: "deny", message, interrupt: !feedback };
|
|
397
399
|
}
|
|
398
400
|
}
|
|
399
401
|
|
|
@@ -169,6 +169,12 @@ export class AgentServer {
|
|
|
169
169
|
private initializationPromise: Promise<void> | null = null;
|
|
170
170
|
private pendingEvents: Record<string, unknown>[] = [];
|
|
171
171
|
|
|
172
|
+
private detachSseController(controller: SseController): void {
|
|
173
|
+
if (this.session?.sseController === controller) {
|
|
174
|
+
this.session.sseController = null;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
172
178
|
private emitConsoleLog = (
|
|
173
179
|
level: LogLevel,
|
|
174
180
|
_scope: string,
|
|
@@ -250,18 +256,15 @@ export class AgentServer {
|
|
|
250
256
|
controller.enqueue(
|
|
251
257
|
new TextEncoder().encode(`data: ${JSON.stringify(data)}\n\n`),
|
|
252
258
|
);
|
|
253
|
-
} catch
|
|
254
|
-
this.
|
|
255
|
-
"SSE send failed (stream may be closed)",
|
|
256
|
-
error,
|
|
257
|
-
);
|
|
259
|
+
} catch {
|
|
260
|
+
this.detachSseController(sseController);
|
|
258
261
|
}
|
|
259
262
|
},
|
|
260
263
|
close: () => {
|
|
261
264
|
try {
|
|
262
265
|
controller.close();
|
|
263
|
-
} catch
|
|
264
|
-
this.
|
|
266
|
+
} catch {
|
|
267
|
+
this.detachSseController(sseController);
|
|
265
268
|
}
|
|
266
269
|
},
|
|
267
270
|
};
|
|
@@ -1577,6 +1580,10 @@ Important:
|
|
|
1577
1580
|
}
|
|
1578
1581
|
|
|
1579
1582
|
private sendSseEvent(controller: SseController, data: unknown): void {
|
|
1580
|
-
|
|
1583
|
+
try {
|
|
1584
|
+
controller.send(data);
|
|
1585
|
+
} catch {
|
|
1586
|
+
this.detachSseController(controller);
|
|
1587
|
+
}
|
|
1581
1588
|
}
|
|
1582
1589
|
}
|
|
@@ -235,6 +235,71 @@ describe("Question relay", () => {
|
|
|
235
235
|
|
|
236
236
|
expect(result.outcome.outcome).toBe("selected");
|
|
237
237
|
});
|
|
238
|
+
|
|
239
|
+
it("keeps auto-approving permissions after SSE send failures", async () => {
|
|
240
|
+
const appendRawLine = vi.fn();
|
|
241
|
+
const brokenSseController = {
|
|
242
|
+
send: vi.fn(() => {
|
|
243
|
+
throw new Error("stream closed");
|
|
244
|
+
}),
|
|
245
|
+
close: vi.fn(),
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
const cloudPermissionServer = server as TestableAgentServer & {
|
|
249
|
+
emitConsoleLog: (
|
|
250
|
+
level: "debug" | "info" | "warn" | "error",
|
|
251
|
+
scope: string,
|
|
252
|
+
message: string,
|
|
253
|
+
data?: unknown,
|
|
254
|
+
) => void;
|
|
255
|
+
logger: { debug: (message: string, data?: unknown) => void };
|
|
256
|
+
session: {
|
|
257
|
+
payload: typeof TEST_PAYLOAD;
|
|
258
|
+
sseController: typeof brokenSseController | null;
|
|
259
|
+
logWriter: {
|
|
260
|
+
appendRawLine: (runId: string, line: string) => void;
|
|
261
|
+
};
|
|
262
|
+
};
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
cloudPermissionServer.session = {
|
|
266
|
+
payload: TEST_PAYLOAD,
|
|
267
|
+
sseController: brokenSseController,
|
|
268
|
+
logWriter: {
|
|
269
|
+
appendRawLine,
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
cloudPermissionServer.logger = {
|
|
273
|
+
debug: (message: string, data?: unknown) => {
|
|
274
|
+
cloudPermissionServer.emitConsoleLog(
|
|
275
|
+
"debug",
|
|
276
|
+
"agent",
|
|
277
|
+
message,
|
|
278
|
+
data,
|
|
279
|
+
);
|
|
280
|
+
},
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
const client = cloudPermissionServer.createCloudClient(TEST_PAYLOAD);
|
|
284
|
+
|
|
285
|
+
const firstResult = await client.requestPermission({
|
|
286
|
+
options: ALLOW_OPTIONS,
|
|
287
|
+
toolCall: { _meta: { codeToolKind: "bash" } },
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
expect(firstResult.outcome.outcome).toBe("selected");
|
|
291
|
+
expect(brokenSseController.send).toHaveBeenCalledTimes(1);
|
|
292
|
+
expect(cloudPermissionServer.session.sseController).toBeNull();
|
|
293
|
+
|
|
294
|
+
const secondResult = await client.requestPermission({
|
|
295
|
+
options: ALLOW_OPTIONS,
|
|
296
|
+
toolCall: { _meta: { codeToolKind: "bash" } },
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
expect(secondResult.outcome.outcome).toBe("selected");
|
|
300
|
+
expect(brokenSseController.send).toHaveBeenCalledTimes(1);
|
|
301
|
+
expect(appendRawLine).toHaveBeenCalledTimes(2);
|
|
302
|
+
});
|
|
238
303
|
});
|
|
239
304
|
});
|
|
240
305
|
|