@posthog/agent 2.3.548 → 2.3.616
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 +105 -31
- package/dist/agent.js.map +1 -1
- package/dist/handoff-checkpoint.js +142 -117
- package/dist/handoff-checkpoint.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 +2 -1
- package/dist/server/agent-server.js +155 -68
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +166 -80
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +3 -3
- package/src/adapters/claude/conversion/sdk-to-acp.ts +1 -26
- package/src/adapters/claude/session/options.ts +8 -0
- package/src/adapters/codex/codex-agent.test.ts +83 -0
- package/src/adapters/codex/codex-agent.ts +16 -0
- package/src/adapters/error-classification.ts +30 -0
- package/src/server/agent-server.ts +17 -7
- package/src/server/question-relay.test.ts +67 -5
package/dist/agent.js
CHANGED
|
@@ -3699,12 +3699,12 @@ var require_src2 = __commonJS({
|
|
|
3699
3699
|
function check(path16, isFile2, isDirectory) {
|
|
3700
3700
|
log(`checking %s`, path16);
|
|
3701
3701
|
try {
|
|
3702
|
-
const
|
|
3703
|
-
if (
|
|
3702
|
+
const stat3 = fs_1.statSync(path16);
|
|
3703
|
+
if (stat3.isFile() && isFile2) {
|
|
3704
3704
|
log(`[OK] path represents a file`);
|
|
3705
3705
|
return true;
|
|
3706
3706
|
}
|
|
3707
|
-
if (
|
|
3707
|
+
if (stat3.isDirectory() && isDirectory) {
|
|
3708
3708
|
log(`[OK] path represents a directory`);
|
|
3709
3709
|
return true;
|
|
3710
3710
|
}
|
|
@@ -4030,7 +4030,7 @@ import { v7 as uuidv7 } from "uuid";
|
|
|
4030
4030
|
// package.json
|
|
4031
4031
|
var package_default = {
|
|
4032
4032
|
name: "@posthog/agent",
|
|
4033
|
-
version: "2.3.
|
|
4033
|
+
version: "2.3.616",
|
|
4034
4034
|
repository: "https://github.com/PostHog/code",
|
|
4035
4035
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
4036
4036
|
exports: {
|
|
@@ -6258,6 +6258,7 @@ var ParserManager = class {
|
|
|
6258
6258
|
languages = /* @__PURE__ */ new Map();
|
|
6259
6259
|
languageKeys = /* @__PURE__ */ new WeakMap();
|
|
6260
6260
|
queryCache = /* @__PURE__ */ new Map();
|
|
6261
|
+
failedQueries = /* @__PURE__ */ new Set();
|
|
6261
6262
|
maxCacheSize = 256;
|
|
6262
6263
|
initPromise = null;
|
|
6263
6264
|
wasmDir = resolveGrammarsDir();
|
|
@@ -6265,6 +6266,7 @@ var ParserManager = class {
|
|
|
6265
6266
|
updateConfig(config) {
|
|
6266
6267
|
this.config = config;
|
|
6267
6268
|
this.queryCache.clear();
|
|
6269
|
+
this.failedQueries.clear();
|
|
6268
6270
|
}
|
|
6269
6271
|
async ensureInitialized() {
|
|
6270
6272
|
if (!this.initPromise) {
|
|
@@ -6326,6 +6328,9 @@ var ParserManager = class {
|
|
|
6326
6328
|
}
|
|
6327
6329
|
const langKey = this.languageKeys.get(lang) ?? lang.toString();
|
|
6328
6330
|
const cacheKey = `${langKey}:${queryStr}`;
|
|
6331
|
+
if (this.failedQueries.has(cacheKey)) {
|
|
6332
|
+
return null;
|
|
6333
|
+
}
|
|
6329
6334
|
let query2 = this.queryCache.get(cacheKey);
|
|
6330
6335
|
if (query2) {
|
|
6331
6336
|
this.queryCache.delete(cacheKey);
|
|
@@ -6342,8 +6347,8 @@ var ParserManager = class {
|
|
|
6342
6347
|
}
|
|
6343
6348
|
this.queryCache.set(cacheKey, query2);
|
|
6344
6349
|
return query2;
|
|
6345
|
-
} catch
|
|
6346
|
-
|
|
6350
|
+
} catch {
|
|
6351
|
+
this.failedQueries.add(cacheKey);
|
|
6347
6352
|
return null;
|
|
6348
6353
|
}
|
|
6349
6354
|
}
|
|
@@ -6354,6 +6359,7 @@ var ParserManager = class {
|
|
|
6354
6359
|
this.languages.clear();
|
|
6355
6360
|
this.languageKeys = /* @__PURE__ */ new WeakMap();
|
|
6356
6361
|
this.queryCache.clear();
|
|
6362
|
+
this.failedQueries.clear();
|
|
6357
6363
|
}
|
|
6358
6364
|
};
|
|
6359
6365
|
async function findVariantBranches(pm, source, languageId) {
|
|
@@ -7879,6 +7885,33 @@ var PostHogApi = class {
|
|
|
7879
7885
|
);
|
|
7880
7886
|
return data.results.filter((f) => !f.deleted);
|
|
7881
7887
|
}
|
|
7888
|
+
// Keys absent from the returned map have NOT been called in the window.
|
|
7889
|
+
async getFlagLastCalled(flagKeys, daysBack = 30) {
|
|
7890
|
+
if (flagKeys.length === 0) return /* @__PURE__ */ new Map();
|
|
7891
|
+
const days = Math.max(1, Math.min(365, Math.floor(daysBack)));
|
|
7892
|
+
const query2 = `
|
|
7893
|
+
SELECT
|
|
7894
|
+
properties.$feature_flag AS flag_key,
|
|
7895
|
+
max(timestamp) AS last_called_at
|
|
7896
|
+
FROM events
|
|
7897
|
+
WHERE event = '$feature_flag_called'
|
|
7898
|
+
AND properties.$feature_flag IN {flagKeys}
|
|
7899
|
+
AND timestamp >= now() - INTERVAL ${days} DAY
|
|
7900
|
+
GROUP BY flag_key
|
|
7901
|
+
`;
|
|
7902
|
+
const data = await this.post("/query/", {
|
|
7903
|
+
query: {
|
|
7904
|
+
kind: "HogQLQuery",
|
|
7905
|
+
query: query2,
|
|
7906
|
+
values: { flagKeys }
|
|
7907
|
+
}
|
|
7908
|
+
});
|
|
7909
|
+
const lastCalled = /* @__PURE__ */ new Map();
|
|
7910
|
+
for (const [flagKey, lastCalledAt] of data.results) {
|
|
7911
|
+
if (lastCalledAt) lastCalled.set(flagKey, lastCalledAt);
|
|
7912
|
+
}
|
|
7913
|
+
return lastCalled;
|
|
7914
|
+
}
|
|
7882
7915
|
async getExperiments() {
|
|
7883
7916
|
const data = await this.get(
|
|
7884
7917
|
"/experiments/?limit=500"
|
|
@@ -8173,9 +8206,9 @@ var PostHogEnricher = class {
|
|
|
8173
8206
|
}
|
|
8174
8207
|
let mtimeMs = 0;
|
|
8175
8208
|
try {
|
|
8176
|
-
const
|
|
8177
|
-
mtimeMs =
|
|
8178
|
-
if (
|
|
8209
|
+
const stat22 = await fs2.stat(absPath);
|
|
8210
|
+
mtimeMs = stat22.mtimeMs;
|
|
8211
|
+
if (stat22.size > MAX_WRAPPER_SOURCE_BYTES) {
|
|
8179
8212
|
return this.setWrapperCache(absPath, mtimeMs, []);
|
|
8180
8213
|
}
|
|
8181
8214
|
} catch {
|
|
@@ -8733,6 +8766,23 @@ function tryParsePartialJson(s) {
|
|
|
8733
8766
|
return null;
|
|
8734
8767
|
}
|
|
8735
8768
|
|
|
8769
|
+
// src/adapters/error-classification.ts
|
|
8770
|
+
var UPSTREAM_PROVIDER_ERROR_STATUS_PATTERN = /API Error:\s*(?:429|5\d\d)\b/i;
|
|
8771
|
+
function classifyAgentError(result) {
|
|
8772
|
+
if (!result) return "agent_error";
|
|
8773
|
+
const text2 = result.trim();
|
|
8774
|
+
if (/API Error:\s*terminated\b/i.test(text2)) {
|
|
8775
|
+
return "upstream_stream_terminated";
|
|
8776
|
+
}
|
|
8777
|
+
if (/API Error:\s*Connection error\b/i.test(text2)) {
|
|
8778
|
+
return "upstream_connection_error";
|
|
8779
|
+
}
|
|
8780
|
+
if (UPSTREAM_PROVIDER_ERROR_STATUS_PATTERN.test(text2)) {
|
|
8781
|
+
return "upstream_provider_failure";
|
|
8782
|
+
}
|
|
8783
|
+
return "agent_error";
|
|
8784
|
+
}
|
|
8785
|
+
|
|
8736
8786
|
// src/adapters/claude/permissions/posthog-exec-gate.ts
|
|
8737
8787
|
var POSTHOG_EXEC_TOOL_RE = /^mcp__posthog(?:_[^_]+)*__exec$/;
|
|
8738
8788
|
var POSTHOG_CALL_COMMAND_RE = /^\s*call\s+(?:--json\s+)?([a-zA-Z0-9_-]+)/;
|
|
@@ -10049,17 +10099,6 @@ async function handleSystemMessage(message, context) {
|
|
|
10049
10099
|
break;
|
|
10050
10100
|
}
|
|
10051
10101
|
}
|
|
10052
|
-
function classifyAgentError(result) {
|
|
10053
|
-
if (!result) return "agent_error";
|
|
10054
|
-
const text2 = result.trim();
|
|
10055
|
-
if (/API Error:\s*terminated\b/i.test(text2)) {
|
|
10056
|
-
return "upstream_stream_terminated";
|
|
10057
|
-
}
|
|
10058
|
-
if (/API Error:\s*Connection error\b/i.test(text2)) {
|
|
10059
|
-
return "upstream_connection_error";
|
|
10060
|
-
}
|
|
10061
|
-
return "agent_error";
|
|
10062
|
-
}
|
|
10063
10102
|
function handleResultMessage(message) {
|
|
10064
10103
|
const usage = extractUsageFromResult(message);
|
|
10065
10104
|
switch (message.subtype) {
|
|
@@ -11290,6 +11329,10 @@ function buildMcpServers(userServers, acpServers, projectScopedServers) {
|
|
|
11290
11329
|
};
|
|
11291
11330
|
}
|
|
11292
11331
|
function buildEnvironment() {
|
|
11332
|
+
const bedrockFallbackHeader = "x-posthog-use-bedrock-fallback: true";
|
|
11333
|
+
const existingCustomHeaders = process.env.ANTHROPIC_CUSTOM_HEADERS;
|
|
11334
|
+
const customHeaders = existingCustomHeaders ? `${existingCustomHeaders}
|
|
11335
|
+
${bedrockFallbackHeader}` : bedrockFallbackHeader;
|
|
11293
11336
|
return {
|
|
11294
11337
|
...process.env,
|
|
11295
11338
|
ELECTRON_RUN_AS_NODE: "1",
|
|
@@ -11297,7 +11340,9 @@ function buildEnvironment() {
|
|
|
11297
11340
|
// Offload all MCP tools by default
|
|
11298
11341
|
ENABLE_TOOL_SEARCH: "auto:0",
|
|
11299
11342
|
// Enable idle state as end-of-turn signal (required for SDK 0.2.114+)
|
|
11300
|
-
CLAUDE_CODE_EMIT_SESSION_STATE_EVENTS: "1"
|
|
11343
|
+
CLAUDE_CODE_EMIT_SESSION_STATE_EVENTS: "1",
|
|
11344
|
+
// Route to AWS Bedrock as a fallback when Anthropic returns 5xx
|
|
11345
|
+
ANTHROPIC_CUSTOM_HEADERS: customHeaders
|
|
11301
11346
|
};
|
|
11302
11347
|
}
|
|
11303
11348
|
function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichmentDeps, enrichedReadCache, registeredAgents) {
|
|
@@ -11558,6 +11603,7 @@ var AsyncMutex = class {
|
|
|
11558
11603
|
};
|
|
11559
11604
|
|
|
11560
11605
|
// ../git/dist/queries.js
|
|
11606
|
+
import { createReadStream } from "fs";
|
|
11561
11607
|
import * as fs7 from "fs/promises";
|
|
11562
11608
|
import * as path11 from "path";
|
|
11563
11609
|
|
|
@@ -16109,13 +16155,20 @@ init_git_response_error();
|
|
|
16109
16155
|
var simpleGit = gitInstanceFactory;
|
|
16110
16156
|
|
|
16111
16157
|
// ../git/dist/client.js
|
|
16158
|
+
var PERFORMANCE_CONFIG = [
|
|
16159
|
+
"core.untrackedCache=true",
|
|
16160
|
+
"core.fsmonitor=true",
|
|
16161
|
+
"core.preloadIndex=true"
|
|
16162
|
+
];
|
|
16112
16163
|
function createGitClient(baseDir, options) {
|
|
16113
|
-
const { abortSignal: signal, ...rest } = options ?? {};
|
|
16164
|
+
const { abortSignal: signal, config: callerConfig, ...rest } = options ?? {};
|
|
16165
|
+
const config = callerConfig ? [...PERFORMANCE_CONFIG, ...callerConfig] : PERFORMANCE_CONFIG;
|
|
16114
16166
|
return simpleGit({
|
|
16115
16167
|
baseDir,
|
|
16116
16168
|
maxConcurrentProcesses: 6,
|
|
16117
16169
|
trimmed: true,
|
|
16118
16170
|
abort: signal,
|
|
16171
|
+
config,
|
|
16119
16172
|
...rest
|
|
16120
16173
|
});
|
|
16121
16174
|
}
|
|
@@ -16137,10 +16190,10 @@ async function getIndexLockPath(repoPath) {
|
|
|
16137
16190
|
async function getLockInfo(repoPath) {
|
|
16138
16191
|
const lockPath = await getIndexLockPath(repoPath);
|
|
16139
16192
|
try {
|
|
16140
|
-
const
|
|
16193
|
+
const stat3 = await fs6.stat(lockPath);
|
|
16141
16194
|
return {
|
|
16142
16195
|
path: lockPath,
|
|
16143
|
-
ageMs: Date.now() -
|
|
16196
|
+
ageMs: Date.now() - stat3.mtimeMs
|
|
16144
16197
|
};
|
|
16145
16198
|
} catch {
|
|
16146
16199
|
return null;
|
|
@@ -16268,14 +16321,18 @@ var GitOperationManagerImpl = class _GitOperationManagerImpl {
|
|
|
16268
16321
|
}
|
|
16269
16322
|
async executeRead(repoPath, operation, options) {
|
|
16270
16323
|
const state = this.getRepoState(repoPath);
|
|
16324
|
+
const env = {
|
|
16325
|
+
...getCleanEnv(),
|
|
16326
|
+
GIT_OPTIONAL_LOCKS: "0",
|
|
16327
|
+
...options?.env
|
|
16328
|
+
};
|
|
16271
16329
|
if (options?.signal) {
|
|
16272
16330
|
const scopedGit = createGitClient(repoPath, {
|
|
16273
16331
|
abortSignal: options.signal
|
|
16274
16332
|
});
|
|
16275
|
-
return operation(scopedGit.env(
|
|
16333
|
+
return operation(scopedGit.env(env));
|
|
16276
16334
|
}
|
|
16277
|
-
|
|
16278
|
-
return operation(git);
|
|
16335
|
+
return operation(state.client.env(env));
|
|
16279
16336
|
}
|
|
16280
16337
|
async executeWrite(repoPath, operation, options) {
|
|
16281
16338
|
const state = this.getRepoState(repoPath);
|
|
@@ -16285,15 +16342,16 @@ var GitOperationManagerImpl = class _GitOperationManagerImpl {
|
|
|
16285
16342
|
throw new Error(`Git repository is locked: ${repoPath}`);
|
|
16286
16343
|
}
|
|
16287
16344
|
}
|
|
16345
|
+
const env = { ...getCleanEnv(), ...options?.env };
|
|
16288
16346
|
await state.lock.acquireWrite();
|
|
16289
16347
|
try {
|
|
16290
16348
|
if (options?.signal) {
|
|
16291
16349
|
const scopedGit = createGitClient(repoPath, {
|
|
16292
16350
|
abortSignal: options.signal
|
|
16293
16351
|
});
|
|
16294
|
-
return await operation(scopedGit.env(
|
|
16352
|
+
return await operation(scopedGit.env(env));
|
|
16295
16353
|
}
|
|
16296
|
-
return await operation(state.client.env(
|
|
16354
|
+
return await operation(state.client.env(env));
|
|
16297
16355
|
} catch (error) {
|
|
16298
16356
|
if (options?.signal?.aborted) {
|
|
16299
16357
|
await removeLock(repoPath).catch(() => {
|
|
@@ -16320,6 +16378,9 @@ function getGitOperationManager() {
|
|
|
16320
16378
|
return instance2;
|
|
16321
16379
|
}
|
|
16322
16380
|
|
|
16381
|
+
// ../git/dist/status-stream.js
|
|
16382
|
+
import { spawn as spawn3 } from "child_process";
|
|
16383
|
+
|
|
16323
16384
|
// ../git/dist/queries.js
|
|
16324
16385
|
async function listWorktrees(baseDir, options) {
|
|
16325
16386
|
const manager = getGitOperationManager();
|
|
@@ -18157,7 +18218,7 @@ function parseCodexToml(content, cwd) {
|
|
|
18157
18218
|
}
|
|
18158
18219
|
|
|
18159
18220
|
// src/adapters/codex/spawn.ts
|
|
18160
|
-
import { spawn as
|
|
18221
|
+
import { spawn as spawn4 } from "child_process";
|
|
18161
18222
|
import { existsSync as existsSync4 } from "fs";
|
|
18162
18223
|
import { delimiter, dirname as dirname5 } from "path";
|
|
18163
18224
|
function buildConfigArgs(options) {
|
|
@@ -18221,7 +18282,7 @@ function spawnCodexProcess(options) {
|
|
|
18221
18282
|
hasApiKey: !!options.apiKey,
|
|
18222
18283
|
binaryPath: options.binaryPath
|
|
18223
18284
|
});
|
|
18224
|
-
const child =
|
|
18285
|
+
const child = spawn4(command, args2, {
|
|
18225
18286
|
cwd: options.cwd,
|
|
18226
18287
|
env,
|
|
18227
18288
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -18279,6 +18340,17 @@ function prependPrContext(params) {
|
|
|
18279
18340
|
prompt: [{ type: "text", text: prContext }, ...params.prompt]
|
|
18280
18341
|
};
|
|
18281
18342
|
}
|
|
18343
|
+
function classifyPromptError(error) {
|
|
18344
|
+
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
18345
|
+
const classification = classifyAgentError(message);
|
|
18346
|
+
if (classification === "agent_error") {
|
|
18347
|
+
return error;
|
|
18348
|
+
}
|
|
18349
|
+
return RequestError3.internalError(
|
|
18350
|
+
{ classification, result: message },
|
|
18351
|
+
message
|
|
18352
|
+
);
|
|
18353
|
+
}
|
|
18282
18354
|
var CODEX_NATIVE_MODE = {
|
|
18283
18355
|
auto: "auto",
|
|
18284
18356
|
default: "auto",
|
|
@@ -18608,6 +18680,8 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18608
18680
|
let response;
|
|
18609
18681
|
try {
|
|
18610
18682
|
response = await this.codexConnection.prompt(prependPrContext(params));
|
|
18683
|
+
} catch (error) {
|
|
18684
|
+
throw classifyPromptError(error);
|
|
18611
18685
|
} finally {
|
|
18612
18686
|
this.session.promptRunning = false;
|
|
18613
18687
|
}
|