@posthog/wizard 2.67.0 → 2.69.0
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/{add-mcp-server-to-clients-DHTRbyJX.js → add-mcp-server-to-clients-Cl2HBuxp.js} +4 -4
- package/dist/{add-mcp-server-to-clients-DHTRbyJX.js.map → add-mcp-server-to-clients-Cl2HBuxp.js.map} +1 -1
- package/dist/{agent-interface-tM_b0l__.js → agent-interface-CI89BrWE.js} +301 -51
- package/dist/agent-interface-CI89BrWE.js.map +1 -0
- package/dist/{agent-prompt-loader-BSMh5bfD.js → agent-prompt-loader-Dc1g5Oub.js} +5 -5
- package/dist/{agent-prompt-loader-BSMh5bfD.js.map → agent-prompt-loader-Dc1g5Oub.js.map} +1 -1
- package/dist/{agent-runner-DD65OMkB.js → agent-runner-D5dhuE4z.js} +38 -18
- package/dist/agent-runner-D5dhuE4z.js.map +1 -0
- package/dist/{analytics-CtIYzkK4.js → analytics-D90QbLf5.js} +2 -2
- package/dist/{analytics-CtIYzkK4.js.map → analytics-D90QbLf5.js.map} +1 -1
- package/dist/analytics-Dmf_Jm3K.js +2 -0
- package/dist/{api-BJft9v6K.js → api-BHhrT6wb.js} +3 -3
- package/dist/{api-BJft9v6K.js.map → api-BHhrT6wb.js.map} +1 -1
- package/dist/bin.js +51 -51
- package/dist/{bounded-fs-BWqoFQvQ.js → bounded-fs-BhlVkP1r.js} +3 -3
- package/dist/{bounded-fs-BWqoFQvQ.js.map → bounded-fs-BhlVkP1r.js.map} +1 -1
- package/dist/{ci-install-BXGnVI7T.js → ci-install-94wC3a4K.js} +5 -5
- package/dist/{ci-install-BXGnVI7T.js.map → ci-install-94wC3a4K.js.map} +1 -1
- package/dist/{debug-BsHD83Vy.js → debug-CifTS9lQ.js} +3 -3
- package/dist/{debug-BsHD83Vy.js.map → debug-CifTS9lQ.js.map} +1 -1
- package/dist/{debug-mO3yg4Z7.js → debug-DtixqVEY.js} +1 -1
- package/dist/{env-api-key-DS0ghlcO.js → env-api-key-CwhtZrik.js} +2 -2
- package/dist/{env-api-key-DS0ghlcO.js.map → env-api-key-CwhtZrik.js.map} +1 -1
- package/dist/environment-DhacWZf7.js +44 -0
- package/dist/environment-DhacWZf7.js.map +1 -0
- package/dist/{errors-BHervYGs.js → errors-BSdz2lsl.js} +3 -2
- package/dist/errors-BSdz2lsl.js.map +1 -0
- package/dist/{file-watcher-D1bdo9mq.js → file-watcher-L28OpUV2.js} +2 -2
- package/dist/{file-watcher-D1bdo9mq.js.map → file-watcher-L28OpUV2.js.map} +1 -1
- package/dist/{headless-ui-6QuByWZ_.js → headless-ui-DNcOVJxU.js} +2 -2
- package/dist/{headless-ui-6QuByWZ_.js.map → headless-ui-DNcOVJxU.js.map} +1 -1
- package/dist/{interactive-DUpW84WU.js → interactive-DlNrV77o.js} +2 -2
- package/dist/{interactive-DUpW84WU.js.map → interactive-DlNrV77o.js.map} +1 -1
- package/dist/{mcp-CHo9h-WV.js → mcp-CJEem9qs.js} +2 -2
- package/dist/{mcp-CHo9h-WV.js.map → mcp-CJEem9qs.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-CHRPxxd0.js → mcp-prompt-streaming-DER7MG3q.js} +13 -12
- package/dist/mcp-prompt-streaming-DER7MG3q.js.map +1 -0
- package/dist/{non-interactive-Cr-chffe.js → non-interactive-CbvniKHm.js} +3 -3
- package/dist/{non-interactive-Cr-chffe.js.map → non-interactive-CbvniKHm.js.map} +1 -1
- package/dist/{orchestrator-tools-Tx18_TMb.js → orchestrator-tools-Czf3Wo_y.js} +3 -3
- package/dist/{orchestrator-tools-Tx18_TMb.js.map → orchestrator-tools-Czf3Wo_y.js.map} +1 -1
- package/dist/{package-manager-CLfc31yf.js → package-manager-CNNlFA2q.js} +2 -2
- package/dist/{package-manager-CLfc31yf.js.map → package-manager-CNNlFA2q.js.map} +1 -1
- package/dist/{pi-RlnYUHdb.js → pi-kpN-bO9z.js} +17 -14
- package/dist/pi-kpN-bO9z.js.map +1 -0
- package/dist/{playground-DQ633rje.js → playground-ZYaQmfBa.js} +7 -7
- package/dist/{playground-DQ633rje.js.map → playground-ZYaQmfBa.js.map} +1 -1
- package/dist/{posthog-DSn9bIZc.js → posthog-D1zHPgYJ.js} +2 -2
- package/dist/{posthog-DSn9bIZc.js.map → posthog-D1zHPgYJ.js.map} +1 -1
- package/dist/{posthog-integration-DFfBRGOC.js → posthog-integration-DdeIUkYw.js} +17 -16
- package/dist/posthog-integration-DdeIUkYw.js.map +1 -0
- package/dist/{provisioning-Cvy_vQHV.js → provisioning-e3roaLgp.js} +3 -3
- package/dist/{provisioning-Cvy_vQHV.js.map → provisioning-e3roaLgp.js.map} +1 -1
- package/dist/{queue-tools-BC9HxOV6.js → queue-tools-zrqCiy6q.js} +3 -3
- package/dist/{queue-tools-BC9HxOV6.js.map → queue-tools-zrqCiy6q.js.map} +1 -1
- package/dist/{registry-DCAElOyj.js → registry-C1t8v5tE.js} +5 -5
- package/dist/{registry-DCAElOyj.js.map → registry-C1t8v5tE.js.map} +1 -1
- package/dist/{security-CuSX3XVo.js → security-CIfhIscL.js} +5 -5
- package/dist/{security-CuSX3XVo.js.map → security-CIfhIscL.js.map} +1 -1
- package/dist/{setup-utils-D1tv0v_R.js → setup-utils-B_06xag2.js} +9 -9
- package/dist/{setup-utils-D1tv0v_R.js.map → setup-utils-B_06xag2.js.map} +1 -1
- package/dist/{start-tui-B5YfmqNr.js → start-tui-BafJXVNT.js} +20 -20
- package/dist/{start-tui-B5YfmqNr.js.map → start-tui-BafJXVNT.js.map} +1 -1
- package/dist/{steps-CLaSMwfR.js → steps-DR-Yo_IT.js} +7 -7
- package/dist/{steps-CLaSMwfR.js.map → steps-DR-Yo_IT.js.map} +1 -1
- package/dist/{store-DzEgsAPN.js → store-DSUCWMRO.js} +5 -5
- package/dist/{store-DzEgsAPN.js.map → store-DSUCWMRO.js.map} +1 -1
- package/dist/{subagent-BUV6aD7p.js → subagent-DjZM3G7y.js} +2 -2
- package/dist/{subagent-BUV6aD7p.js.map → subagent-DjZM3G7y.js.map} +1 -1
- package/dist/{task-GnWId75q.js → task-Czzz3tzt.js} +18 -15
- package/dist/task-Czzz3tzt.js.map +1 -0
- package/dist/{task-stream-DSzvwJrD.js → task-stream-uxG6wJfj.js} +6 -6
- package/dist/{task-stream-DSzvwJrD.js.map → task-stream-uxG6wJfj.js.map} +1 -1
- package/dist/{tasks-BO0W8ocx.js → tasks-CVmG8qFw.js} +2 -2
- package/dist/{tasks-BO0W8ocx.js.map → tasks-CVmG8qFw.js.map} +1 -1
- package/dist/{telemetry-Vi9dWddJ.js → telemetry-B1VEXHpL.js} +3 -3
- package/dist/{telemetry-Vi9dWddJ.js.map → telemetry-B1VEXHpL.js.map} +1 -1
- package/dist/{terminal-B5wZK7aS.js → terminal-Czuo0x8i.js} +12 -12
- package/dist/{terminal-B5wZK7aS.js.map → terminal-Czuo0x8i.js.map} +1 -1
- package/dist/{tools-C9cNluqc.js → tools-DOZg9n3A.js} +10 -7
- package/dist/tools-DOZg9n3A.js.map +1 -0
- package/dist/{wizard-abort-BsNbguJt.js → wizard-abort-BZOeapsf.js} +1 -1
- package/dist/{wizard-abort-CGv3lVxw.js → wizard-abort-CFMdj6sZ.js} +5 -5
- package/dist/{wizard-abort-CGv3lVxw.js.map → wizard-abort-CFMdj6sZ.js.map} +1 -1
- package/dist/{wizard-session-Cex1BiXs.js → wizard-session-C_7r3-rO.js} +2 -1
- package/dist/wizard-session-C_7r3-rO.js.map +1 -0
- package/dist/{wizard-session-DHbUcjI7.js → wizard-session-D1KQqUml.js} +1 -1
- package/dist/yara-hooks-BhNAWw7W.js +2 -0
- package/dist/{yara-hooks-DZIVzhA6.js → yara-hooks-CmQT-oBy.js} +4 -4
- package/dist/{yara-hooks-DZIVzhA6.js.map → yara-hooks-CmQT-oBy.js.map} +1 -1
- package/package.json +1 -1
- package/dist/agent-interface-tM_b0l__.js.map +0 -1
- package/dist/agent-runner-DD65OMkB.js.map +0 -1
- package/dist/analytics-B4Igh5nv.js +0 -2
- package/dist/environment-C7CKGIOE.js +0 -22
- package/dist/environment-C7CKGIOE.js.map +0 -1
- package/dist/errors-BHervYGs.js.map +0 -1
- package/dist/mcp-prompt-streaming-CHRPxxd0.js.map +0 -1
- package/dist/pi-RlnYUHdb.js.map +0 -1
- package/dist/posthog-integration-DFfBRGOC.js.map +0 -1
- package/dist/task-GnWId75q.js.map +0 -1
- package/dist/tools-C9cNluqc.js.map +0 -1
- package/dist/wizard-session-Cex1BiXs.js.map +0 -1
- package/dist/yara-hooks-C3Vm2Gow.js +0 -2
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { n as __require } from "./rolldown-runtime-B_-DWIq7.js";
|
|
2
|
-
import { a as AgentSignals, o as REMARK_INSTRUCTION, s as classifyAuthFailure } from "./errors-
|
|
3
|
-
import { G as POSTHOG_FLAG_HEADER_PREFIX, J as POSTHOG_PROPERTY_HEADER_PREFIX, a as getLogFilePath, dt as WIZARD_REMARK_EVENT_NAME, f as getUI, ht as wizardUserAgentForProgram, o as initLogFile, r as debug, s as logToFile, xt as runtimeEnv } from "./debug-
|
|
4
|
-
import { n as analytics } from "./analytics-
|
|
5
|
-
import { a as safeReadFile, i as readProjectFile, o as walkProjectFiles } from "./bounded-fs-
|
|
6
|
-
import { n as ADDITIONAL_FEATURE_PROMPTS } from "./wizard-session-
|
|
7
|
-
import { i as wizardAbort, n as registerCleanup, t as WizardError } from "./wizard-abort-
|
|
8
|
-
import { _ as modelCapabilities, m as writeJsonAtomic, o as buildOrchestratorTools, p as makeMutex, y as triageModelFor } from "./queue-tools-
|
|
9
|
-
import { b as coerceAuditChecks, g as AUDIT_CHECKS_FILE, l as prewarmYaraScanner, n as createPostToolUseYaraHooks, p as scanInstalledSkill, r as createPreToolUseYaraHooks } from "./yara-hooks-
|
|
2
|
+
import { a as AgentSignals, o as REMARK_INSTRUCTION, s as classifyAuthFailure } from "./errors-BSdz2lsl.js";
|
|
3
|
+
import { G as POSTHOG_FLAG_HEADER_PREFIX, J as POSTHOG_PROPERTY_HEADER_PREFIX, a as getLogFilePath, dt as WIZARD_REMARK_EVENT_NAME, f as getUI, ht as wizardUserAgentForProgram, o as initLogFile, r as debug, s as logToFile, xt as runtimeEnv } from "./debug-CifTS9lQ.js";
|
|
4
|
+
import { n as analytics } from "./analytics-D90QbLf5.js";
|
|
5
|
+
import { a as safeReadFile, i as readProjectFile, o as walkProjectFiles } from "./bounded-fs-BhlVkP1r.js";
|
|
6
|
+
import { n as ADDITIONAL_FEATURE_PROMPTS } from "./wizard-session-C_7r3-rO.js";
|
|
7
|
+
import { i as wizardAbort, n as registerCleanup, t as WizardError } from "./wizard-abort-CFMdj6sZ.js";
|
|
8
|
+
import { _ as modelCapabilities, m as writeJsonAtomic, o as buildOrchestratorTools, p as makeMutex, y as triageModelFor } from "./queue-tools-zrqCiy6q.js";
|
|
9
|
+
import { b as coerceAuditChecks, g as AUDIT_CHECKS_FILE, l as prewarmYaraScanner, n as createPostToolUseYaraHooks, p as scanInstalledSkill, r as createPreToolUseYaraHooks } from "./yara-hooks-CmQT-oBy.js";
|
|
10
10
|
import { createRequire } from "node:module";
|
|
11
11
|
import * as fs$1 from "fs";
|
|
12
12
|
import fs from "fs";
|
|
@@ -19,6 +19,228 @@ import { z } from "zod";
|
|
|
19
19
|
import * as os from "os";
|
|
20
20
|
import { unzipSync } from "fflate";
|
|
21
21
|
import { randomUUID } from "crypto";
|
|
22
|
+
//#region src/lib/gateway-session.ts
|
|
23
|
+
/**
|
|
24
|
+
* Gateway auth for a wizard run: a `phe_` scoped token the backend mints, with
|
|
25
|
+
* pinned attribution, a spend cap and an expiry.
|
|
26
|
+
*
|
|
27
|
+
* A 404 resolves to the legacy posture (OAuth token, Python gateway); every
|
|
28
|
+
* other failure throws, because the legacy path enforces none of those, so a
|
|
29
|
+
* silent downgrade spends unattributed money to hide an outage.
|
|
30
|
+
*/
|
|
31
|
+
let cached = null;
|
|
32
|
+
/**
|
|
33
|
+
* Shared so concurrent callers mint once. The orchestrator starts every runnable
|
|
34
|
+
* task at once, and each would otherwise take its own token and its own cap.
|
|
35
|
+
*/
|
|
36
|
+
let inFlight = null;
|
|
37
|
+
/**
|
|
38
|
+
* Adoption floor. The anthropic subprocess holds its credential for the whole
|
|
39
|
+
* session, so a token below this 401s mid-run.
|
|
40
|
+
*/
|
|
41
|
+
const MIN_USABLE_TTL_MS = 120 * 1e3;
|
|
42
|
+
/** Re-resolve at this fraction of the token's life, leaving a usable remainder. */
|
|
43
|
+
const REFRESH_AT_FRACTION = .8;
|
|
44
|
+
/** How long a legacy fallback sticks before the mint endpoint is retried. */
|
|
45
|
+
const LEGACY_RETRY_MS = 600 * 1e3;
|
|
46
|
+
const MINT_TIMEOUT_MS = 2e4;
|
|
47
|
+
/** Resolve this run's gateway auth, minting and re-minting near expiry. */
|
|
48
|
+
async function gatewayAuth(host, accessToken, program) {
|
|
49
|
+
const key = `${host.apiHost}\n${accessToken}\n${program ?? ""}`;
|
|
50
|
+
if (cached && cached.key === key && Date.now() < cached.staleAtMs) return cached.auth;
|
|
51
|
+
if (inFlight && inFlight.key === key) return inFlight.promise;
|
|
52
|
+
const promise = resolveGatewayAuth(host, accessToken, key, program);
|
|
53
|
+
inFlight = {
|
|
54
|
+
key,
|
|
55
|
+
promise
|
|
56
|
+
};
|
|
57
|
+
try {
|
|
58
|
+
return await promise;
|
|
59
|
+
} finally {
|
|
60
|
+
if (inFlight?.promise === promise) inFlight = null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async function resolveGatewayAuth(host, accessToken, key, program) {
|
|
64
|
+
if (!program) {
|
|
65
|
+
logToFile("[gateway] run has no program id; failing the run");
|
|
66
|
+
throw new GatewayMintFailed("this run has no program to attribute its spend to");
|
|
67
|
+
}
|
|
68
|
+
const minted = await mintGatewayToken(host, accessToken, program);
|
|
69
|
+
if (!minted) {
|
|
70
|
+
analytics.setTag("gateway_edition", "legacy");
|
|
71
|
+
const auth = legacyAuth(host, accessToken);
|
|
72
|
+
cached = {
|
|
73
|
+
key,
|
|
74
|
+
auth,
|
|
75
|
+
staleAtMs: Date.now() + LEGACY_RETRY_MS
|
|
76
|
+
};
|
|
77
|
+
return auth;
|
|
78
|
+
}
|
|
79
|
+
const expiresAtMs = Date.parse(minted.expiresAt);
|
|
80
|
+
const ttlMs = expiresAtMs - Date.now();
|
|
81
|
+
if (!Number.isFinite(expiresAtMs) || ttlMs < MIN_USABLE_TTL_MS) {
|
|
82
|
+
logToFile(`[gateway] mint returned a token with ${ttlMs}ms of life; failing the run`);
|
|
83
|
+
throw new GatewayMintFailed(`the PostHog gateway issued a token with ${ttlMs}ms of life`);
|
|
84
|
+
}
|
|
85
|
+
const staleAtMs = Date.now() + ttlMs * REFRESH_AT_FRACTION;
|
|
86
|
+
analytics.setTag("gateway_edition", "v2");
|
|
87
|
+
const auth = {
|
|
88
|
+
gatewayUrl: minted.gatewayUrl,
|
|
89
|
+
token: minted.token,
|
|
90
|
+
edition: "v2",
|
|
91
|
+
teamId: minted.teamId
|
|
92
|
+
};
|
|
93
|
+
cached = {
|
|
94
|
+
key,
|
|
95
|
+
auth,
|
|
96
|
+
staleAtMs
|
|
97
|
+
};
|
|
98
|
+
return auth;
|
|
99
|
+
}
|
|
100
|
+
/** The legacy posture: the user's OAuth token against the Python gateway. */
|
|
101
|
+
function legacyAuth(host, accessToken) {
|
|
102
|
+
return {
|
|
103
|
+
gatewayUrl: host.gatewayUrl,
|
|
104
|
+
token: accessToken,
|
|
105
|
+
edition: "legacy"
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Whether a server-supplied origin may receive a bearer and prompt content:
|
|
110
|
+
* https (loopback excepted), and either a posthog.com host or the one the run
|
|
111
|
+
* authenticated against.
|
|
112
|
+
*/
|
|
113
|
+
function isTrustedGatewayUrl(value, apiHost) {
|
|
114
|
+
let url;
|
|
115
|
+
try {
|
|
116
|
+
url = new URL(value);
|
|
117
|
+
} catch {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
if (url.pathname !== "/" || url.search || url.hash || url.username || url.password) return false;
|
|
121
|
+
if (url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "host.docker.internal") return true;
|
|
122
|
+
if (url.protocol !== "https:") return false;
|
|
123
|
+
if (url.hostname.endsWith(".posthog.com")) return true;
|
|
124
|
+
try {
|
|
125
|
+
return url.hostname === new URL(apiHost).hostname;
|
|
126
|
+
} catch {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* A deliberate refusal from the mint endpoint, as opposed to the mint being
|
|
132
|
+
* unavailable. Thrown rather than folded into the legacy fallback, so the run
|
|
133
|
+
* stops instead of proceeding without the controls the refusal was enforcing.
|
|
134
|
+
*/
|
|
135
|
+
var GatewayMintRefused = class extends Error {
|
|
136
|
+
status;
|
|
137
|
+
constructor(status, message) {
|
|
138
|
+
super(message);
|
|
139
|
+
this.name = "GatewayMintRefused";
|
|
140
|
+
this.status = status;
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* The mint could not produce a usable credential: unreachable, a 5xx, or a
|
|
145
|
+
* response the client cannot use.
|
|
146
|
+
*/
|
|
147
|
+
var GatewayMintFailed = class extends Error {
|
|
148
|
+
constructor(message) {
|
|
149
|
+
super(message);
|
|
150
|
+
this.name = "GatewayMintFailed";
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Whether a mint status means "refused this run" rather than "not available".
|
|
155
|
+
* These are the statuses the endpoint returns after it has authenticated the
|
|
156
|
+
* caller: 429 the daily run limit, 403 revoked project access, 400 a login
|
|
157
|
+
* covering more than one project. 404 and 401 fall back instead.
|
|
158
|
+
*/
|
|
159
|
+
function isMintRefusal(status) {
|
|
160
|
+
return status === 400 || status === 403 || status === 429;
|
|
161
|
+
}
|
|
162
|
+
function mintRefusalMessage(status) {
|
|
163
|
+
switch (status) {
|
|
164
|
+
case 429: return "This wizard program has used its daily run limit. Try again tomorrow.";
|
|
165
|
+
case 403: return "Your access to this project has changed. Re-authenticate and try again.";
|
|
166
|
+
case 400: return "Your PostHog login must cover exactly one project. Re-authenticate and try again.";
|
|
167
|
+
default: return "The PostHog gateway refused this run.";
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
async function mintGatewayToken(host, accessToken, program) {
|
|
171
|
+
try {
|
|
172
|
+
const resp = await fetch(`${host.apiHost}/api/wizard/gateway_token/`, {
|
|
173
|
+
method: "POST",
|
|
174
|
+
headers: {
|
|
175
|
+
Authorization: `Bearer ${accessToken}`,
|
|
176
|
+
"Content-Type": "application/json"
|
|
177
|
+
},
|
|
178
|
+
body: JSON.stringify({ program }),
|
|
179
|
+
signal: AbortSignal.timeout(MINT_TIMEOUT_MS)
|
|
180
|
+
});
|
|
181
|
+
if (!resp.ok) {
|
|
182
|
+
if (isMintRefusal(resp.status)) {
|
|
183
|
+
logToFile(`[gateway] mint refused with HTTP ${resp.status}; failing the run`);
|
|
184
|
+
throw new GatewayMintRefused(resp.status, mintRefusalMessage(resp.status));
|
|
185
|
+
}
|
|
186
|
+
if (resp.status === 404 || resp.status === 401) {
|
|
187
|
+
logToFile(`[gateway] mint unavailable for this credential (HTTP ${resp.status}); staying on the existing gateway`);
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
logToFile(`[gateway] mint failed with HTTP ${resp.status}; failing the run`);
|
|
191
|
+
throw new GatewayMintFailed(`the PostHog gateway could not issue a token (HTTP ${resp.status})`);
|
|
192
|
+
}
|
|
193
|
+
const body = await resp.json();
|
|
194
|
+
if (!body.token) {
|
|
195
|
+
logToFile("[gateway] mint response omitted token; failing the run");
|
|
196
|
+
throw new GatewayMintFailed("mint response omitted token");
|
|
197
|
+
}
|
|
198
|
+
if (!body.expires_at) {
|
|
199
|
+
logToFile("[gateway] mint response omitted expires_at; failing the run");
|
|
200
|
+
throw new GatewayMintFailed("mint response omitted expires_at");
|
|
201
|
+
}
|
|
202
|
+
if (!body.gateway_url) {
|
|
203
|
+
logToFile("[gateway] mint response omitted gateway_url; failing the run");
|
|
204
|
+
throw new GatewayMintFailed("mint response omitted gateway_url");
|
|
205
|
+
}
|
|
206
|
+
if (!isTrustedGatewayUrl(body.gateway_url, host.apiHost)) {
|
|
207
|
+
logToFile("[gateway] mint returned an untrusted gateway url; failing the run");
|
|
208
|
+
throw new GatewayMintFailed("mint returned an untrusted gateway url");
|
|
209
|
+
}
|
|
210
|
+
return {
|
|
211
|
+
token: body.token,
|
|
212
|
+
expiresAt: body.expires_at,
|
|
213
|
+
gatewayUrl: body.gateway_url.replace(/\/+$/, ""),
|
|
214
|
+
teamId: body.team_id
|
|
215
|
+
};
|
|
216
|
+
} catch (e) {
|
|
217
|
+
if (e instanceof GatewayMintRefused || e instanceof GatewayMintFailed) throw e;
|
|
218
|
+
logToFile(`[gateway] mint transport failure (${String(e)}); failing the run`);
|
|
219
|
+
throw new GatewayMintFailed(`could not reach the PostHog gateway (${String(e)})`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* The v2 run-metadata carrier: one JSON blob for the `X-PostHog-Properties`
|
|
224
|
+
* header. Plain keys only, since the gateway strips `$`-prefixed keys as reserved,
|
|
225
|
+
* so feature-flag variants land as `wizard_flag_<key>` instead of the legacy
|
|
226
|
+
* `$feature/<key>` (dashboards keying on `$feature/wizard-*` read the new key
|
|
227
|
+
* post-cutover).
|
|
228
|
+
*/
|
|
229
|
+
function buildWizardPropertiesBlob(wizardMetadata, wizardFlags, teamId) {
|
|
230
|
+
const props = {};
|
|
231
|
+
if (teamId !== void 0) props.team_id = teamId;
|
|
232
|
+
for (const [key, value] of Object.entries(wizardMetadata)) props[stripPropertyPrefix(key)] = value;
|
|
233
|
+
for (const [flagKey, variant] of Object.entries(wizardFlags)) {
|
|
234
|
+
if (!flagKey.toLowerCase().startsWith("wizard")) continue;
|
|
235
|
+
props[`wizard_flag_${flagKey.toLowerCase()}`] = variant;
|
|
236
|
+
}
|
|
237
|
+
return JSON.stringify(props);
|
|
238
|
+
}
|
|
239
|
+
const LEGACY_PROPERTY_PREFIX = "X-POSTHOG-PROPERTY-";
|
|
240
|
+
function stripPropertyPrefix(key) {
|
|
241
|
+
return key.toUpperCase().startsWith(LEGACY_PROPERTY_PREFIX) ? key.slice(19).toLowerCase() : key;
|
|
242
|
+
}
|
|
243
|
+
//#endregion
|
|
22
244
|
//#region src/lib/agent/runner/harness/pi/gateway.ts
|
|
23
245
|
/**
|
|
24
246
|
* PostHog LLM gateway provider spec for pi sessions — shared by the linear run
|
|
@@ -32,23 +254,33 @@ const GATEWAY_PROVIDER = "posthog-gateway";
|
|
|
32
254
|
/**
|
|
33
255
|
* The gateway speaks two shapes on two endpoints: Anthropic models over
|
|
34
256
|
* `anthropic-messages` (the SDK appends `/v1/messages`, so the base URL has no
|
|
35
|
-
* `/v1`), and OpenAI-class models (`openai/gpt-5`, …) over OpenAI
|
|
36
|
-
* `/v1/chat/completions` (base URL keeps `/v1`). Infer the
|
|
37
|
-
* id so a pair's model selects the right transport.
|
|
257
|
+
* `/v1`), and OpenAI-class models (`openai/gpt-5`, …) over an OpenAI shape at
|
|
258
|
+
* `/v1/responses` or `/v1/chat/completions` (base URL keeps `/v1`). Infer the
|
|
259
|
+
* shape from the model id so a pair's model selects the right transport.
|
|
260
|
+
*
|
|
261
|
+
* v2 takes the Responses API because OpenAI rejects function tools combined
|
|
262
|
+
* with `reasoning_effort` on chat completions and every task sends both. Legacy
|
|
263
|
+
* stays on chat completions, where litellm does that routing itself.
|
|
38
264
|
*/
|
|
39
|
-
function gatewayApiFor(modelId) {
|
|
40
|
-
|
|
265
|
+
function gatewayApiFor(modelId, edition = "legacy") {
|
|
266
|
+
if (!modelId.startsWith("openai/")) return "anthropic-messages";
|
|
267
|
+
return edition === "v2" ? "openai-responses" : "openai-completions";
|
|
41
268
|
}
|
|
42
269
|
/**
|
|
43
|
-
* Gateway HTTP headers, mirroring `buildAgentEnv` on the anthropic path
|
|
44
|
-
* the
|
|
45
|
-
*
|
|
270
|
+
* Gateway HTTP headers, mirroring `buildAgentEnv` on the anthropic path. The
|
|
271
|
+
* shape follows the gateway edition: legacy sends per-key metadata/flag
|
|
272
|
+
* headers plus the explicit Bedrock-fallback opt-in; v2 (the Go ai-gateway)
|
|
273
|
+
* takes one `X-PostHog-Properties` JSON blob and falls back natively. The 1M
|
|
274
|
+
* context beta rides both, since pi otherwise runs at 200k and overflows on larger
|
|
275
|
+
* projects (the post-run compaction failures).
|
|
46
276
|
*/
|
|
47
|
-
function buildGatewayHeaders(wizardMetadata, wizardFlags) {
|
|
48
|
-
const headers = {
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
|
|
277
|
+
function buildGatewayHeaders(wizardMetadata, wizardFlags, edition = "legacy", teamId) {
|
|
278
|
+
const headers = { "anthropic-beta": "context-1m-2025-08-07" };
|
|
279
|
+
if (edition === "v2") {
|
|
280
|
+
headers["X-PostHog-Properties"] = buildWizardPropertiesBlob(wizardMetadata, wizardFlags, teamId);
|
|
281
|
+
return headers;
|
|
282
|
+
}
|
|
283
|
+
headers["x-posthog-use-bedrock-fallback"] = "true";
|
|
52
284
|
for (const [key, value] of Object.entries(wizardMetadata)) {
|
|
53
285
|
const name = key.startsWith("X-POSTHOG-PROPERTY-") ? key : `${POSTHOG_PROPERTY_HEADER_PREFIX}${key}`;
|
|
54
286
|
headers[name] = value;
|
|
@@ -65,14 +297,14 @@ function buildGatewayHeaders(wizardMetadata, wizardFlags) {
|
|
|
65
297
|
* callers (scan triage) hand it straight to `completeSimple`.
|
|
66
298
|
*/
|
|
67
299
|
function buildGatewayModel(inputs) {
|
|
68
|
-
const { gatewayUrl, wizardMetadata, wizardFlags, modelId } = inputs;
|
|
69
|
-
const api = gatewayApiFor(modelId);
|
|
300
|
+
const { gatewayUrl, wizardMetadata, wizardFlags, modelId, edition, teamId } = inputs;
|
|
301
|
+
const api = gatewayApiFor(modelId, edition);
|
|
70
302
|
return {
|
|
71
303
|
id: modelId,
|
|
72
304
|
name: `${modelId} (PostHog Gateway)`,
|
|
73
305
|
api,
|
|
74
306
|
provider: GATEWAY_PROVIDER,
|
|
75
|
-
baseUrl: api === "
|
|
307
|
+
baseUrl: api === "anthropic-messages" ? gatewayUrl : `${gatewayUrl}/v1`,
|
|
76
308
|
reasoning: modelCapabilities(modelId).reasoning,
|
|
77
309
|
input: ["text"],
|
|
78
310
|
cost: {
|
|
@@ -83,7 +315,7 @@ function buildGatewayModel(inputs) {
|
|
|
83
315
|
},
|
|
84
316
|
contextWindow: 1e6,
|
|
85
317
|
maxTokens: 64e3,
|
|
86
|
-
headers: buildGatewayHeaders(wizardMetadata, wizardFlags)
|
|
318
|
+
headers: buildGatewayHeaders(wizardMetadata, wizardFlags, edition, teamId)
|
|
87
319
|
};
|
|
88
320
|
}
|
|
89
321
|
/**
|
|
@@ -91,12 +323,12 @@ function buildGatewayModel(inputs) {
|
|
|
91
323
|
* plus the derived traits the session setup needs (`caps.thinkingLevel`).
|
|
92
324
|
*/
|
|
93
325
|
function buildGatewayProvider(inputs) {
|
|
94
|
-
const { gatewayUrl, accessToken, modelId, effort } = inputs;
|
|
95
|
-
const api = gatewayApiFor(modelId);
|
|
326
|
+
const { gatewayUrl, accessToken, modelId, effort, edition } = inputs;
|
|
327
|
+
const api = gatewayApiFor(modelId, edition);
|
|
96
328
|
const tableCaps = modelCapabilities(modelId);
|
|
97
|
-
const caps = effort && tableCaps.reasoning ? {
|
|
329
|
+
const caps = effort && effort !== "off" && tableCaps.reasoning ? modelCapabilities(modelId, effort) : effort === "off" && tableCaps.reasoning ? {
|
|
98
330
|
...tableCaps,
|
|
99
|
-
thinkingLevel:
|
|
331
|
+
thinkingLevel: "off"
|
|
100
332
|
} : tableCaps;
|
|
101
333
|
const model = buildGatewayModel(inputs);
|
|
102
334
|
return {
|
|
@@ -131,6 +363,8 @@ function createTriageLLMProvider(auth, harness) {
|
|
|
131
363
|
const model = buildGatewayModel({
|
|
132
364
|
gatewayUrl: baseURL,
|
|
133
365
|
accessToken: authToken,
|
|
366
|
+
edition: auth.edition,
|
|
367
|
+
teamId: auth.teamId,
|
|
134
368
|
wizardMetadata: auth?.wizardMetadata ?? {},
|
|
135
369
|
wizardFlags: auth?.wizardFlags ?? {},
|
|
136
370
|
modelId
|
|
@@ -836,7 +1070,7 @@ function isFullyCancelled(answers) {
|
|
|
836
1070
|
}
|
|
837
1071
|
function createWizardAskBridge(opts) {
|
|
838
1072
|
const timeoutMs = opts.timeoutMs ?? 3e5;
|
|
839
|
-
return { async request({ questions }) {
|
|
1073
|
+
return { async request({ questions, subject }) {
|
|
840
1074
|
const pending = {
|
|
841
1075
|
id: randomUUID(),
|
|
842
1076
|
questions,
|
|
@@ -857,12 +1091,14 @@ function createWizardAskBridge(opts) {
|
|
|
857
1091
|
const durationMs = Date.now() - startedAt;
|
|
858
1092
|
if (isFullyCancelled(answers)) analytics.wizardCapture("wizard_ask cancelled", {
|
|
859
1093
|
source: pending.source,
|
|
1094
|
+
subject,
|
|
860
1095
|
question_count: questions.length,
|
|
861
1096
|
duration_ms: durationMs,
|
|
862
1097
|
timed_out: durationMs >= timeoutMs
|
|
863
1098
|
});
|
|
864
1099
|
else analytics.wizardCapture("wizard_ask answered", {
|
|
865
1100
|
source: pending.source,
|
|
1101
|
+
subject,
|
|
866
1102
|
question_count: questions.length,
|
|
867
1103
|
duration_ms: durationMs
|
|
868
1104
|
});
|
|
@@ -1926,7 +2162,10 @@ async function createWizardToolsServer(options) {
|
|
|
1926
2162
|
}
|
|
1927
2163
|
askAccounting.record(args.subject);
|
|
1928
2164
|
try {
|
|
1929
|
-
const answers = await askBridge.request({
|
|
2165
|
+
const answers = await askBridge.request({
|
|
2166
|
+
questions: args.questions,
|
|
2167
|
+
subject: normaliseAskSubject(args.subject)
|
|
2168
|
+
});
|
|
1930
2169
|
if (isFullyCancelled(answers)) askAccounting.refund(args.subject);
|
|
1931
2170
|
const sanitised = vaultSensitiveAnswers(args.questions, answers, secretVault);
|
|
1932
2171
|
logToFile(`wizard_ask: resolved ${Object.keys(answers).length} answer(s) for ${args.questions.length} question(s)`);
|
|
@@ -2774,17 +3013,23 @@ function isWarlockDisabled() {
|
|
|
2774
3013
|
return runtimeEnv("POSTHOG_WIZARD_WARLOCK_DISABLED") === "true";
|
|
2775
3014
|
}
|
|
2776
3015
|
/**
|
|
2777
|
-
* Build env for the SDK subprocess: process.env plus ANTHROPIC_CUSTOM_HEADERS
|
|
2778
|
-
*
|
|
2779
|
-
*
|
|
3016
|
+
* Build env for the SDK subprocess: process.env plus ANTHROPIC_CUSTOM_HEADERS.
|
|
3017
|
+
* The header shape follows the gateway edition. Legacy (Python gateway):
|
|
3018
|
+
* per-key `X-POSTHOG-PROPERTY-*`/`X-POSTHOG-FLAG-*` plus the explicit
|
|
3019
|
+
* `x-posthog-use-bedrock-fallback` opt-in. v2 (Go ai-gateway): one
|
|
3020
|
+
* `X-PostHog-Properties` JSON blob. Bedrock fallback is native there, and
|
|
3021
|
+
* per-key metadata headers are not read.
|
|
2780
3022
|
*/
|
|
2781
|
-
function buildAgentEnv(wizardMetadata, wizardFlags) {
|
|
3023
|
+
function buildAgentEnv(wizardMetadata, wizardFlags, auth) {
|
|
2782
3024
|
const headers = createCustomHeaders();
|
|
2783
|
-
headers.add("
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
3025
|
+
if (auth?.edition === "v2") headers.add("X-PostHog-Properties", buildWizardPropertiesBlob(wizardMetadata, wizardFlags, auth.teamId));
|
|
3026
|
+
else {
|
|
3027
|
+
headers.add("x-posthog-use-bedrock-fallback", "true");
|
|
3028
|
+
for (const [key, value] of Object.entries(wizardMetadata)) headers.add(key.startsWith("X-POSTHOG-PROPERTY-") ? key : `${POSTHOG_PROPERTY_HEADER_PREFIX}${key}`, value);
|
|
3029
|
+
for (const [flagKey, variant] of Object.entries(wizardFlags)) {
|
|
3030
|
+
if (!flagKey.toLowerCase().startsWith("wizard")) continue;
|
|
3031
|
+
headers.addFlag(flagKey, variant);
|
|
3032
|
+
}
|
|
2788
3033
|
}
|
|
2789
3034
|
const encoded = headers.encode();
|
|
2790
3035
|
logToFile("ANTHROPIC_CUSTOM_HEADERS", encoded);
|
|
@@ -2879,13 +3124,17 @@ async function initializeAgent(config, options) {
|
|
|
2879
3124
|
logToFile("Install directory:", options.installDir);
|
|
2880
3125
|
try {
|
|
2881
3126
|
process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS = "true";
|
|
2882
|
-
const
|
|
3127
|
+
const auth = await gatewayAuth(config.host, config.posthogApiKey, config.programId);
|
|
3128
|
+
const gatewayUrl = auth.gatewayUrl;
|
|
2883
3129
|
process.env.ANTHROPIC_BASE_URL = gatewayUrl;
|
|
2884
|
-
process.env.ANTHROPIC_AUTH_TOKEN =
|
|
2885
|
-
process.env.CLAUDE_CODE_OAUTH_TOKEN =
|
|
3130
|
+
process.env.ANTHROPIC_AUTH_TOKEN = auth.token;
|
|
3131
|
+
process.env.CLAUDE_CODE_OAUTH_TOKEN = auth.token;
|
|
3132
|
+
logToFile("Gateway edition:", auth.edition);
|
|
2886
3133
|
const triageProvider = createTriageLLMProvider({
|
|
2887
3134
|
baseURL: gatewayUrl,
|
|
2888
|
-
authToken:
|
|
3135
|
+
authToken: auth.token,
|
|
3136
|
+
edition: auth.edition,
|
|
3137
|
+
teamId: auth.teamId,
|
|
2889
3138
|
wizardMetadata: {
|
|
2890
3139
|
...config.wizardMetadata ?? {},
|
|
2891
3140
|
call_type: "yara-triage"
|
|
@@ -2942,6 +3191,7 @@ async function initializeAgent(config, options) {
|
|
|
2942
3191
|
suppressTaskRender: !!config.orchestrator,
|
|
2943
3192
|
capture: config.capture,
|
|
2944
3193
|
triageProvider,
|
|
3194
|
+
gatewayAuth: auth,
|
|
2945
3195
|
program: config.integrationLabel,
|
|
2946
3196
|
sequence: config.orchestrator ? "orchestrator" : "linear"
|
|
2947
3197
|
};
|
|
@@ -3115,13 +3365,13 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
|
|
|
3115
3365
|
},
|
|
3116
3366
|
env: {
|
|
3117
3367
|
...sanitizeAgentSubprocessEnv(process.env),
|
|
3118
|
-
ANTHROPIC_BASE_URL:
|
|
3119
|
-
ANTHROPIC_AUTH_TOKEN:
|
|
3120
|
-
CLAUDE_CODE_OAUTH_TOKEN:
|
|
3368
|
+
ANTHROPIC_BASE_URL: agentConfig.gatewayAuth.gatewayUrl,
|
|
3369
|
+
ANTHROPIC_AUTH_TOKEN: agentConfig.gatewayAuth.token,
|
|
3370
|
+
CLAUDE_CODE_OAUTH_TOKEN: agentConfig.gatewayAuth.token,
|
|
3121
3371
|
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: "true",
|
|
3122
3372
|
POSTHOG_MCP_TOKEN: agentConfig.posthogApiKey,
|
|
3123
3373
|
MCP_CONNECTION_NONBLOCKING: "0",
|
|
3124
|
-
ANTHROPIC_CUSTOM_HEADERS: buildAgentEnv(agentConfig.wizardMetadata ?? {}, agentConfig.wizardFlags ?? {})
|
|
3374
|
+
ANTHROPIC_CUSTOM_HEADERS: buildAgentEnv(agentConfig.wizardMetadata ?? {}, agentConfig.wizardFlags ?? {}, agentConfig.gatewayAuth)
|
|
3125
3375
|
},
|
|
3126
3376
|
canUseTool: (toolName, input) => {
|
|
3127
3377
|
logToFile("canUseTool called:", {
|
|
@@ -3200,7 +3450,7 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
|
|
|
3200
3450
|
if (message.type === "assistant" && signals.hasApiErrorStatus(401)) {
|
|
3201
3451
|
signalDone();
|
|
3202
3452
|
spinner.stop("Authentication failed");
|
|
3203
|
-
const authError = buildAuthErrorContext(options.installDir,
|
|
3453
|
+
const authError = buildAuthErrorContext(options.installDir, agentConfig.gatewayAuth.gatewayUrl, os.homedir(), signals.apiKeySource);
|
|
3204
3454
|
const authCode = classifyAuthFailure({
|
|
3205
3455
|
hasSettingsConflict: authError.hasSettingsConflict,
|
|
3206
3456
|
usingManagedLogin: authError.usingManagedLogin,
|
|
@@ -3572,6 +3822,6 @@ function handleSDKMessage(message, options, spinner, signals, receivedSuccessRes
|
|
|
3572
3822
|
}
|
|
3573
3823
|
}
|
|
3574
3824
|
//#endregion
|
|
3575
|
-
export { installSkillById as A,
|
|
3825
|
+
export { installSkillById as A, MAX_ENV_KEY_SET as B, WIZARD_ASK_SUBJECT_DESCRIPTION as C, createAskAccounting as D, checkEnvKeys as E, templateEnvWriteRefusal as F, GATEWAY_PROVIDER as G, parseEnvKeyNames as H, vaultSensitiveAnswers as I, buildGatewayProvider as K, fetchWithRetry as L, normaliseAskSubject as M, resolveEnvPath as N, downloadSkill as O, resolveEnvSecretRefs as P, createWizardAskBridge as R, WIZARD_ASK_SENSITIVE_DESCRIPTION as S, WIZARD_TOOL_NAMES as T, toPromptSafeRelativePath as U, isEnvFileName as V, createTriageLLMProvider as W, PUBLISH_HANDOFF_TOOL_NAME as _, wizardCanUseTool as a, CHECK_ENV_KEYS_FILE_PATH_DESCRIPTION as b, classifySettingsConflicts as c, sanitizeAgentSubprocessEnv as d, AgentOutputSignals as f, PUBLISH_HANDOFF_DESCRIPTION as g, PUBLISH_HANDOFF_CONTENT_DESCRIPTION as h, runAgent as i, mergeEnvValues as j, fetchSkillMenu as k, recoverOrphanedSettingsBackups as l, createSecretVault as m, buildRunTags as n, backupAndFixClaudeSettings as o, assembleCommandments as p, gatewayAuth as q, initializeAgent as r, checkAllSettingsConflicts as s, buildAgentEnv as t, restoreClaudeSettings as u, publishHandoff as v, WIZARD_ASK_TOOL_DESCRIPTION as w, ENV_FILE_PATH_DESCRIPTION as x, CHECK_ENV_KEYS_DESCRIPTION as y, isFullyCancelled as z };
|
|
3576
3826
|
|
|
3577
|
-
//# sourceMappingURL=agent-interface-
|
|
3827
|
+
//# sourceMappingURL=agent-interface-CI89BrWE.js.map
|