@posthog/ai 8.10.4 → 8.11.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/adk/index.cjs +1 -1
- package/dist/adk/index.mjs +1 -1
- package/dist/anthropic/index.cjs +1 -1
- package/dist/anthropic/index.mjs +1 -1
- package/dist/gemini/index.cjs +1 -1
- package/dist/gemini/index.mjs +1 -1
- package/dist/index.cjs +120 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +28 -0
- package/dist/index.mjs +120 -2
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +1 -1
- package/dist/langchain/index.mjs +1 -1
- package/dist/langchain/middleware/index.cjs +1 -1
- package/dist/langchain/middleware/index.mjs +1 -1
- package/dist/openai/index.cjs +1 -1
- package/dist/openai/index.mjs +1 -1
- package/dist/openai-agents/index.cjs +1 -1
- package/dist/openai-agents/index.mjs +1 -1
- package/dist/vercel/index.cjs +1 -1
- package/dist/vercel/index.mjs +1 -1
- package/package.json +2 -2
package/dist/adk/index.cjs
CHANGED
package/dist/adk/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { BasePlugin } from "@google/adk";
|
|
|
2
2
|
import { v4 } from "uuid";
|
|
3
3
|
import { toJsonSafeValue, uuidv7 } from "@posthog/core";
|
|
4
4
|
//#region package.json
|
|
5
|
-
var version = "8.
|
|
5
|
+
var version = "8.11.0";
|
|
6
6
|
//#endregion
|
|
7
7
|
//#region src/captureAiEvent.ts
|
|
8
8
|
/** @internal */
|
package/dist/anthropic/index.cjs
CHANGED
package/dist/anthropic/index.mjs
CHANGED
package/dist/gemini/index.cjs
CHANGED
package/dist/gemini/index.mjs
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -392,7 +392,7 @@ function sanitizeValues(obj) {
|
|
|
392
392
|
}
|
|
393
393
|
//#endregion
|
|
394
394
|
//#region package.json
|
|
395
|
-
var version = "8.
|
|
395
|
+
var version = "8.11.0";
|
|
396
396
|
//#endregion
|
|
397
397
|
//#region src/serializeError.ts
|
|
398
398
|
const DEFAULT_MAX_DEPTH = 3;
|
|
@@ -1084,6 +1084,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
|
|
|
1084
1084
|
//#region src/prompts.ts
|
|
1085
1085
|
const DEFAULT_CACHE_TTL_SECONDS = 300;
|
|
1086
1086
|
const DEFAULT_PROMPTS_HOST = "https://us.posthog.com";
|
|
1087
|
+
const MAX_PROMPT_LIST_PAGES = 100;
|
|
1087
1088
|
const DEFAULT_REFETCH_COOLDOWN_SECONDS = 60;
|
|
1088
1089
|
const MAX_REFETCH_COOLDOWN_SECONDS = 3600;
|
|
1089
1090
|
function normalizeApiKey(value) {
|
|
@@ -1121,6 +1122,31 @@ function isPromptApiResponse(data) {
|
|
|
1121
1122
|
const record = data;
|
|
1122
1123
|
return typeof record.prompt === "string" && typeof record.name === "string" && typeof record.version === "number" && (record.label === void 0 || typeof record.label === "string");
|
|
1123
1124
|
}
|
|
1125
|
+
function isSameOrigin(url, host) {
|
|
1126
|
+
try {
|
|
1127
|
+
return new URL(url).origin === new URL(host).origin;
|
|
1128
|
+
} catch {
|
|
1129
|
+
return false;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
/**
|
|
1133
|
+
* Classify how a list row relates to the requested label, via its all_labels
|
|
1134
|
+
* field.
|
|
1135
|
+
*
|
|
1136
|
+
* 'resolved': the row is the version the label points to.
|
|
1137
|
+
* 'moved': the prompt carries the label, but on another version. Happens when
|
|
1138
|
+
* the label moves between the query and the response.
|
|
1139
|
+
* 'absent': the prompt does not carry the label at any version. A server that
|
|
1140
|
+
* filters by label never returns such a row, so this means the server ignored
|
|
1141
|
+
* the label param (an older PostHog release) and served latest versions.
|
|
1142
|
+
*/
|
|
1143
|
+
function rowLabelState(row, label) {
|
|
1144
|
+
const allLabels = row.all_labels;
|
|
1145
|
+
if (!Array.isArray(allLabels)) return "absent";
|
|
1146
|
+
const entry = allLabels.find((candidate) => typeof candidate === "object" && candidate !== null && candidate.name === label);
|
|
1147
|
+
if (entry === void 0) return "absent";
|
|
1148
|
+
return entry.version === row.version ? "resolved" : "moved";
|
|
1149
|
+
}
|
|
1124
1150
|
function isPromptsWithPostHog(options) {
|
|
1125
1151
|
return "posthog" in options;
|
|
1126
1152
|
}
|
|
@@ -1155,6 +1181,9 @@ function isPromptsWithPostHog(options) {
|
|
|
1155
1181
|
* label: 'production',
|
|
1156
1182
|
* })
|
|
1157
1183
|
*
|
|
1184
|
+
* // Or fetch all prompts at a label in one request and warm the cache
|
|
1185
|
+
* const prodPrompts = await prompts.getAll({ label: 'production' })
|
|
1186
|
+
*
|
|
1158
1187
|
* // Compile with variables
|
|
1159
1188
|
* const systemPrompt = prompts.compile(result.prompt, {
|
|
1160
1189
|
* company: 'Acme Corp',
|
|
@@ -1221,6 +1250,61 @@ var Prompts = class {
|
|
|
1221
1250
|
}
|
|
1222
1251
|
}
|
|
1223
1252
|
/**
|
|
1253
|
+
* Fetch every prompt that carries a label, in one batch.
|
|
1254
|
+
*
|
|
1255
|
+
* Returns an object mapping prompt name to `PromptRemoteResult`, with each
|
|
1256
|
+
* prompt at the version the label points to. Prompts without the label are
|
|
1257
|
+
* not included.
|
|
1258
|
+
*
|
|
1259
|
+
* Each fetched prompt is stored in the cache, so later
|
|
1260
|
+
* `get(name, { label })` calls are served from cache within the TTL. An app
|
|
1261
|
+
* with many prompts can call this once per cache cycle instead of making one
|
|
1262
|
+
* `get()` request per prompt.
|
|
1263
|
+
*
|
|
1264
|
+
* Throws if the request fails, or if the server does not support fetching
|
|
1265
|
+
* prompts by label on the list endpoint (PostHog releases from before
|
|
1266
|
+
* September 2026).
|
|
1267
|
+
*/
|
|
1268
|
+
async getAll(options) {
|
|
1269
|
+
const label = options.label;
|
|
1270
|
+
const rows = await this.fetchPromptListFromApi(label);
|
|
1271
|
+
const resolvedRows = [];
|
|
1272
|
+
const skipped = [];
|
|
1273
|
+
for (const row of rows) {
|
|
1274
|
+
if (!isPromptApiResponse(row)) throw new Error(`[PostHog Prompts] Invalid response format for prompts with label "${label}"`);
|
|
1275
|
+
const labelState = rowLabelState(row, label);
|
|
1276
|
+
if (labelState === "absent") throw new Error(`[PostHog Prompts] The server returned a prompt that does not carry label "${label}". It may not support fetching prompts by label on the list endpoint yet. Upgrade PostHog, or fetch prompts one by one with get().`);
|
|
1277
|
+
if (labelState === "moved") {
|
|
1278
|
+
skipped.push(row.name);
|
|
1279
|
+
continue;
|
|
1280
|
+
}
|
|
1281
|
+
resolvedRows.push(row);
|
|
1282
|
+
}
|
|
1283
|
+
const now = Date.now();
|
|
1284
|
+
const results = /* @__PURE__ */ new Map();
|
|
1285
|
+
for (const row of resolvedRows) {
|
|
1286
|
+
const config = extractConfig(row.config);
|
|
1287
|
+
this.getOrCreatePromptCache(row.name).set(label, {
|
|
1288
|
+
prompt: row.prompt,
|
|
1289
|
+
name: row.name,
|
|
1290
|
+
version: row.version,
|
|
1291
|
+
label,
|
|
1292
|
+
config,
|
|
1293
|
+
fetchedAt: now
|
|
1294
|
+
});
|
|
1295
|
+
results.set(row.name, {
|
|
1296
|
+
source: "api",
|
|
1297
|
+
prompt: row.prompt,
|
|
1298
|
+
name: row.name,
|
|
1299
|
+
version: row.version,
|
|
1300
|
+
label,
|
|
1301
|
+
config: cloneConfig(config)
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
if (skipped.length > 0) console.warn(`[PostHog Prompts] Skipped ${skipped.length} prompt(s) that did not resolve label "${label}": ${skipped.join(", ")}`);
|
|
1305
|
+
return Object.fromEntries(results);
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1224
1308
|
* Internal method that handles cache + fetch logic, returning full metadata.
|
|
1225
1309
|
* Does NOT handle the string `fallback` option — callers handle that.
|
|
1226
1310
|
*/
|
|
@@ -1310,9 +1394,43 @@ var Prompts = class {
|
|
|
1310
1394
|
promptVersions?.delete(version);
|
|
1311
1395
|
if (promptVersions?.size === 0) this.cache.delete(name);
|
|
1312
1396
|
}
|
|
1313
|
-
|
|
1397
|
+
requireCredentials() {
|
|
1314
1398
|
if (!this.personalApiKey) throw new Error("[PostHog Prompts] personalApiKey is required to fetch prompts. Please provide it when initializing the Prompts instance.");
|
|
1315
1399
|
if (!this.projectApiKey) throw new Error("[PostHog Prompts] projectApiKey is required to fetch prompts. Please provide it when initializing the Prompts instance.");
|
|
1400
|
+
}
|
|
1401
|
+
/**
|
|
1402
|
+
* Fetch all prompts at a label from the paginated list endpoint.
|
|
1403
|
+
* Follows pagination links until the last page and returns the raw rows.
|
|
1404
|
+
*/
|
|
1405
|
+
async fetchPromptListFromApi(label) {
|
|
1406
|
+
this.requireCredentials();
|
|
1407
|
+
const query = `token=${encodeURIComponent(this.projectApiKey)}&label=${encodeURIComponent(label)}&content=full`;
|
|
1408
|
+
let url = `${this.host}/api/environments/@current/llm_prompts/?${query}`;
|
|
1409
|
+
const reference = `prompts with label "${label}"`;
|
|
1410
|
+
const rows = [];
|
|
1411
|
+
let pages = 0;
|
|
1412
|
+
while (url !== void 0) {
|
|
1413
|
+
if (pages >= MAX_PROMPT_LIST_PAGES) throw new Error(`[PostHog Prompts] ${reference} spans more than ${MAX_PROMPT_LIST_PAGES} pages. Refusing to return an incomplete result.`);
|
|
1414
|
+
const response = await fetch(url, {
|
|
1415
|
+
method: "GET",
|
|
1416
|
+
headers: { Authorization: `Bearer ${this.personalApiKey}` }
|
|
1417
|
+
});
|
|
1418
|
+
if (!response.ok) {
|
|
1419
|
+
if (response.status === 403) throw new Error(`[PostHog Prompts] Access denied for ${reference}. Check that your personalApiKey has the correct permissions and the LLM prompts feature is enabled.`);
|
|
1420
|
+
throw new PromptFetchError(`[PostHog Prompts] Failed to fetch ${reference}: HTTP ${response.status}`, response.status === 429 ? parseRetryAfterSeconds(response.headers?.get("Retry-After")) : void 0);
|
|
1421
|
+
}
|
|
1422
|
+
const data = await response.json();
|
|
1423
|
+
if (typeof data !== "object" || data === null || !Array.isArray(data.results)) throw new Error(`[PostHog Prompts] Invalid response format for ${reference}`);
|
|
1424
|
+
rows.push(...data.results);
|
|
1425
|
+
const nextUrl = data.next;
|
|
1426
|
+
if (nextUrl !== null && nextUrl !== void 0 && (typeof nextUrl !== "string" || !isSameOrigin(nextUrl, this.host))) throw new Error(`[PostHog Prompts] Refusing to follow a pagination link off the configured host while fetching ${reference}.`);
|
|
1427
|
+
url = nextUrl === null || nextUrl === void 0 ? void 0 : nextUrl;
|
|
1428
|
+
pages += 1;
|
|
1429
|
+
}
|
|
1430
|
+
return rows;
|
|
1431
|
+
}
|
|
1432
|
+
async fetchPromptFromApi(name, version, label) {
|
|
1433
|
+
this.requireCredentials();
|
|
1316
1434
|
const encodedPromptName = encodeURIComponent(name);
|
|
1317
1435
|
const encodedProjectApiKey = encodeURIComponent(this.projectApiKey);
|
|
1318
1436
|
const versionQuery = version === void 0 ? "" : `&version=${encodeURIComponent(String(version))}`;
|