@posthog/agent 2.3.297 → 2.3.298
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 +104 -1
- package/dist/agent.js.map +1 -1
- package/dist/index.d.ts +3 -6
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/posthog-api.js +1 -1
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.js +105 -3
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +105 -3
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +1 -1
- package/src/acp-extensions.test.ts +72 -0
- package/src/acp-extensions.ts +37 -6
- package/src/adapters/claude/claude-agent.refresh.test.ts +292 -0
- package/src/adapters/claude/claude-agent.ts +121 -1
package/dist/agent.js
CHANGED
|
@@ -245,7 +245,7 @@ import { v7 as uuidv7 } from "uuid";
|
|
|
245
245
|
// package.json
|
|
246
246
|
var package_default = {
|
|
247
247
|
name: "@posthog/agent",
|
|
248
|
-
version: "2.3.
|
|
248
|
+
version: "2.3.298",
|
|
249
249
|
repository: "https://github.com/PostHog/code",
|
|
250
250
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
251
251
|
exports: {
|
|
@@ -414,6 +414,22 @@ var POSTHOG_NOTIFICATIONS = {
|
|
|
414
414
|
/** Response to a relayed permission request (plan approval, question) */
|
|
415
415
|
PERMISSION_RESPONSE: "_posthog/permission_response"
|
|
416
416
|
};
|
|
417
|
+
var POSTHOG_METHODS = {
|
|
418
|
+
/**
|
|
419
|
+
* Client requests a session refresh between turns. Payload may include
|
|
420
|
+
* `mcpServers` to trigger a resume-with-new-options reinit; future fields
|
|
421
|
+
* can extend this without adding new methods. Returns once the refresh has
|
|
422
|
+
* completed so the caller can safely send the next prompt.
|
|
423
|
+
*/
|
|
424
|
+
REFRESH_SESSION: "_posthog/refresh_session"
|
|
425
|
+
};
|
|
426
|
+
function matchesExt(method, expected) {
|
|
427
|
+
if (!method) return false;
|
|
428
|
+
return method === expected || method === `_${expected}`;
|
|
429
|
+
}
|
|
430
|
+
function isMethod(method, expected) {
|
|
431
|
+
return matchesExt(method, expected);
|
|
432
|
+
}
|
|
417
433
|
|
|
418
434
|
// src/utils/common.ts
|
|
419
435
|
async function withTimeout(operation, timeoutMs) {
|
|
@@ -3704,6 +3720,93 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3704
3720
|
this.session.pendingMessages.clear();
|
|
3705
3721
|
await this.session.query.interrupt();
|
|
3706
3722
|
}
|
|
3723
|
+
/**
|
|
3724
|
+
* Refresh the session between turns. Currently the only refreshable field
|
|
3725
|
+
* is `mcpServers` — a resume-with-new-options reinit that bakes the servers
|
|
3726
|
+
* into query() options (preserving conversation history via resume).
|
|
3727
|
+
*
|
|
3728
|
+
* This is an `extMethod` (request/response), not `extNotification`, so the
|
|
3729
|
+
* caller can await completion before sending the next prompt. The sandbox
|
|
3730
|
+
* agent-server uses this on pre-prompt TTL checks.
|
|
3731
|
+
*
|
|
3732
|
+
* Why resume+rebuild instead of query.setMcpServers()?
|
|
3733
|
+
* setMcpServers() does NOT always overwrite servers installed by local/plugin
|
|
3734
|
+
* config — it can non-deterministically surface either the config-provided
|
|
3735
|
+
* server or the plugin-installed one. In the sandbox, repos may have Claude
|
|
3736
|
+
* plugins with their own MCPs, and we want the CLI-supplied set to fully win.
|
|
3737
|
+
* Passing mcpServers via query() options (as a "managed"/static set) has that
|
|
3738
|
+
* overwrite guarantee, so we tear down the current Query and construct a new
|
|
3739
|
+
* one with resume.
|
|
3740
|
+
*
|
|
3741
|
+
* Caller contract: only call REFRESH_SESSION between turns (no prompt in flight).
|
|
3742
|
+
*/
|
|
3743
|
+
async extMethod(method, params) {
|
|
3744
|
+
if (!isMethod(method, POSTHOG_METHODS.REFRESH_SESSION)) {
|
|
3745
|
+
throw RequestError2.methodNotFound(method);
|
|
3746
|
+
}
|
|
3747
|
+
if (params.mcpServers === void 0) {
|
|
3748
|
+
throw new RequestError2(
|
|
3749
|
+
-32602,
|
|
3750
|
+
"refresh_session requires at least one refreshable field (e.g. mcpServers)"
|
|
3751
|
+
);
|
|
3752
|
+
}
|
|
3753
|
+
if (!Array.isArray(params.mcpServers)) {
|
|
3754
|
+
throw new RequestError2(
|
|
3755
|
+
-32602,
|
|
3756
|
+
"refresh_session: mcpServers must be an array"
|
|
3757
|
+
);
|
|
3758
|
+
}
|
|
3759
|
+
const mcpServers = parseMcpServers(
|
|
3760
|
+
params
|
|
3761
|
+
);
|
|
3762
|
+
await this.refreshSession(mcpServers);
|
|
3763
|
+
return { refreshed: true };
|
|
3764
|
+
}
|
|
3765
|
+
async refreshSession(mcpServers) {
|
|
3766
|
+
const prev = this.session;
|
|
3767
|
+
if (prev.promptRunning) {
|
|
3768
|
+
throw new RequestError2(
|
|
3769
|
+
-32002,
|
|
3770
|
+
"Cannot refresh session while a prompt turn is in flight"
|
|
3771
|
+
);
|
|
3772
|
+
}
|
|
3773
|
+
if (prev.modelId && !supportsMcpInjection(prev.modelId)) {
|
|
3774
|
+
throw new RequestError2(
|
|
3775
|
+
-32002,
|
|
3776
|
+
`Model ${prev.modelId} does not support MCP injection; cannot refresh`
|
|
3777
|
+
);
|
|
3778
|
+
}
|
|
3779
|
+
this.logger.info("Refreshing session with fresh MCP servers", {
|
|
3780
|
+
serverCount: Object.keys(mcpServers).length,
|
|
3781
|
+
sessionId: this.sessionId
|
|
3782
|
+
});
|
|
3783
|
+
prev.abortController.abort();
|
|
3784
|
+
await prev.query.interrupt();
|
|
3785
|
+
prev.input.end();
|
|
3786
|
+
const newAbortController = new AbortController();
|
|
3787
|
+
const { sessionId: _drop, ...rest } = prev.queryOptions;
|
|
3788
|
+
const newOptions = {
|
|
3789
|
+
...rest,
|
|
3790
|
+
mcpServers,
|
|
3791
|
+
resume: this.sessionId,
|
|
3792
|
+
forkSession: false,
|
|
3793
|
+
abortController: newAbortController
|
|
3794
|
+
};
|
|
3795
|
+
const newInput = new Pushable();
|
|
3796
|
+
const newQuery = query({ prompt: newInput, options: newOptions });
|
|
3797
|
+
prev.query = newQuery;
|
|
3798
|
+
prev.input = newInput;
|
|
3799
|
+
prev.queryOptions = newOptions;
|
|
3800
|
+
prev.abortController = newAbortController;
|
|
3801
|
+
const result = await withTimeout(
|
|
3802
|
+
newQuery.initializationResult(),
|
|
3803
|
+
SESSION_VALIDATION_TIMEOUT_MS
|
|
3804
|
+
);
|
|
3805
|
+
if (result.result === "timeout") {
|
|
3806
|
+
throw new Error(`Session refresh timed out for ${this.sessionId}`);
|
|
3807
|
+
}
|
|
3808
|
+
this.deferBackgroundFetches(newQuery);
|
|
3809
|
+
}
|
|
3707
3810
|
async unstable_setSessionModel(params) {
|
|
3708
3811
|
await this.session.query.setModel(toSdkModelId(params.modelId));
|
|
3709
3812
|
this.session.modelId = params.modelId;
|